AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 129747
Accepted
Steffen Mangold
Steffen Mangold
Asked: 2016-02-19 16:39:56 +0800 CST2016-02-19 16:39:56 +0800 CST 2016-02-19 16:39:56 +0800 CST

RIGHT JOIN não funcionou como esperado

  • 772

Estou com uma dúvida sobre a junção de duas tabelas.

Esquema

CREATE TABLE [dbo].[DCString] (
    [ID] [bigint] IDENTITY(1,1) NOT NULL,
    [DCDistributionBoxID] [bigint] NOT NULL,
    [CurrentMPP] [decimal](18, 2) NULL,
    CONSTRAINT [PrimaryKey3] PRIMARY KEY CLUSTERED ( [ID] ASC )
)

ALTER TABLE [dbo].[DCString]
    ADD CONSTRAINT [FK_DCString_DCDistributionBox] FOREIGN KEY([DCDistributionBoxID])
    REFERENCES [dbo].[DCDistributionBox] ([ID])

CREATE TABLE [dbo].[StringData](
    [DCStringID] [bigint] NOT NULL,
    [TimeStamp] [datetime] NOT NULL,
    [DCCurrent] [decimal](18, 2) NULL,
    CONSTRAINT [PrimaryKey4] PRIMARY KEY CLUSTERED ( [TimeStamp] DESC, [DCStringID] ASC)
)

A [StringData]tabela tem as seguintes estatísticas de armazenamento:

  • Espaço para dados: 26.901,86 MB
  • Contagem de linhas: 131.827.749
  • Particionado: verdadeiro
  • Contagem de partições: 62
Uso

Agora quero juntar os dados da [StringData]tabela com os dados da [DCString]tabela.

Algo como:

declare @begin datetime = '22.02.2016';
declare @end datetime = '23.02.2016';
declare @dcStringID bigint = 6658;

SELECT [DCString].[ID], [StringData].[TimeStamp]
FROM [StringData]
RIGHT OUTER JOIN [StringData] ON [StringData].[DCStringID] = [DCString].[ID]
WHERE [StringData].[ID] = @dcStringID
AND [StringData].[TimeStamp] >= @begin
AND [StringData].[TimeStamp] < @end;

O que eu espero no intervalo de datas pesquisado onde [StringData]existem dados correspondentes na tabela é o seguinte:

ID   | TimeStamp
6658 | 22.02.2016 10:00:00
6658 | 22.02.2016 11:00:00
6658 | 22.02.2016 12:00:00

... e em um intervalo de datas pesquisado em que não [StringData]existem dados correspondentes na tabela é este:

ID   | TimeStamp
6658 | NULL

Pergunta

O que recebo em um intervalo de datas pesquisado em que não [StringData]existem dados correspondentes na tabela é um resultado de 0 linhas. Por quê?

Eu simplesmente quero sempre obter todos os [DCString].[ID]s. O que há de errado com meu JOIN ou eu errei completamente?

Atualização 1 (relacionada à resposta de @Aaron Bertrand):

Já tentei do seu jeito, mas tenho que cancelar o teste da consulta porque depois de 10min ainda está rodando. Ficou assim:

declare @begin datetime = '22.02.2016';
declare @end datetime = '23.02.2016';
declare @dcStringID bigint = 6658;

SELECT [DCString].[ID], [StringData].[TimeStamp]    
FROM [StringData]    
LEFT JOIN [DCString] 
    ON [StringData].[DCStringID] = [DCString].[ID] 
    AND [StringData].[TimeStamp] >= @begin
    AND [StringData].[TimeStamp] < @end
WHERE [StringData].[ID] = @dcStringID;
sql-server sql-server-2008
  • 2 2 respostas
  • 2744 Views

2 respostas

  • Voted
  1. Best Answer
    Aaron Bertrand
    2016-02-19T17:40:27+08:002016-02-19T17:40:27+08:00

    Se entendi seus requisitos corretamente, você deseja cada linha em DCString, mesmo quando não houver linha correspondente em StringData. As duas consultas que você tem agora estão incorretas:

    1. O primeiro executa DCString RIGHT JOIN StringData- isso é inverso ao que você parece querer (e é uma das razões pelas quais as pessoas sãs evitam RIGHT JOINsempre que possível).
    2. A segunda consulta é executada StringData LEFT JOIN DCString- isso também é inverso ao que você parece querer. Sugeri mudar o RIGHT JOINpara a LEFT JOIN, sem alterar a ordem da tabela, mas você trocou as tabelas também, sem alteração líquida. Por que aquele não está voltando no momento pode ser devido a muitas coisas, não temos como especular. Tente gerar um plano estimado e veja se você está sendo vítima de algum desses motivos .

    Novamente, com base no que eu acho que você deseja (você obterá respostas melhores se fornecer alguns dados de amostra e os resultados desejados):

    -- don't use regional, ambiguous formats like dd.mm.yyyy:
    -- also you can declare multiple variables in one statement
    
    DECLARE @begin datetime    = '20160222',
            @end   datetime    = '20160223',
            @dcStringID bigint = 6658;
    
    -- don't litter your code with square brackets except where necessary:
    
    SELECT d.ID, s.[TimeStamp] -- bad choice for a column name
    
    -- always use schema prefix!
    FROM dbo.DCString AS d
    LEFT OUTER JOIN dbo.StringData AS s
      ON d.ID = s.DCStringID
      AND s.[TimeStamp] >= @begin
      AND s.[TimeStamp] <  @end
    WHERE d.ID = @dcStringID;
    

    Leitura adicional:

    • Formatos de data ambíguos
    • Prefixo do esquema
    • 6
  2. James K. Lowden
    2016-02-19T19:11:01+08:002016-02-19T19:11:01+08:00

    A resposta de Aaron Bertrand está correta e seu conselho é bom. Sua interpretação de "atualização 1" não é a mesma que a consulta dele. Aposto que se você copiar o código literalmente, funcionará.

    Pode ajudar pensar em "externo" e "interno" como conjuntos em um diagrama de Venn com um círculo aninhado dentro do outro: a mesa externa é o conjunto que contém a mesa interna. Portanto, quando dizemos R left outer join S, queremos dizer que a mesa à esquerda, R, é a de fora.

    Algumas pessoas chamam a tabela externa de tabela preservada para reforçar a ideia de que todas as suas linhas são preservadas no JOIN. Também ouvi as colunas da tabela externa serem chamadas de coluna vertebral que "pendura" os dados da tabela interna.

    A razão para preferir a ESQUERDA à DIREITA é psicológica. A maioria das pessoas parece organizar o SELECT para colocar as colunas da tabela externa primeiro (à esquerda) e mencionar a tabela externa primeiro na cláusula FROM. Portanto, todas as "coisas importantes" estão à esquerda e as "poderosas" estão à direita. Eu sei por mim mesmo que sempre que alguém me traz uma junção DIREITA que não está funcionando como esperado, a primeira coisa que faço é reformulá-la como uma junção ESQUERDA, e isso geralmente é suficiente para ver o que está errado.

    • 4

relate perguntas

  • Quais são as principais causas de deadlocks e podem ser evitadas?

  • Quanto "Padding" coloco em meus índices?

  • Existe um processo do tipo "práticas recomendadas" para os desenvolvedores seguirem para alterações no banco de dados?

  • Como determinar se um Índice é necessário ou necessário

  • Downgrade do SQL Server 2008 para 2005

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host

    • 12 respostas
  • Marko Smith

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Jin conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve