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 / 260768
Accepted
Joseph Shirk
Joseph Shirk
Asked: 2020-02-28 12:59:15 +0800 CST2020-02-28 12:59:15 +0800 CST 2020-02-28 12:59:15 +0800 CST

Cláusula JOIN ON estranha no T-SQL

  • 772

Estou desembaraçando alguns códigos legados e nunca em todos os meus anos vi isso:

Select * 

FROM GLAccounts
INNER JOIN GLCharts
    ON glaGLChartID = glcGLChartID
LEFT JOIN GLCategories
    ON glcGLCategoryID = gltGLCategoryID
INNER JOIN GLDepartments
    ON glaGLDepartmentID = gldGLDepartmentID
INNER JOIN GLDivisions
    ON glaGLDivisionID = glvGLDivisionID
        ,GLFiscalYearPeriods                --<this comma>
INNER JOIN GLFiscalYears
    ON glfGLFiscalYearID = glzGLFiscalYearID


ORDER BY glcGLCategoryID
    ,glcParentGLChartID
    ,glaGLChartID

a junção funciona, mas não encontro esse uso de vírgula em nenhuma referência de sintaxe T-SQL para a cláusula ON.

O que está acontecendo aqui? TIA

sql-server t-sql
  • 3 3 respostas
  • 1663 Views

3 respostas

  • Voted
  1. Best Answer
    McNets
    2020-02-28T14:25:01+08:002020-02-28T14:25:01+08:00

    GLFiscalYearPeriods é uma tabela e esta vírgula implica uma junção cruzada. (Produto cartesiano)

    Parece que a consulta retorna alguns valores para cada ano fiscal.

    Dadas essas tabelas:

    create table a (id int, foo int);
    create table c (id int);
    insert into a values (1,1),(2,2),(3,3);
    insert into c values (10),(20);
    
    select * from a, c;
    
    select * from a cross join c;
    
    identificação | foo | Eu iria
    -: | --: | -:
     1 | 1 | 10
     2 | 2 | 10
     3 | 3 | 10
     1 | 1 | 20
     2 | 2 | 20
     3 | 3 | 20
    

    db<>fique aqui

    Só mais um exemplo:

    create table a (id int, foo int);
    create table b (id int, foo int);
    create table c (id int);
    create table d (id int);
    insert into a values (1,1),(2,2),(3,3);
    insert into b values (1,1),(2,2),(3,3);
    insert into c values (10),(20);
    insert into d values (1),(2);
    
    select * from a join b on a.id = b.id       ,     c join d on d.id = a.id ;
    

    Msg 4104 Nível 16 Estado 1 Linha 1
    O identificador de várias partes "a.id" não pôde ser vinculado.

    mas se você fizer a junção cruzada:

    select * from a join b on a.id = b.id  cross join  c join d on d.id = a.id ;
    
    identificação | foo | identificação | foo | identificação | Eu iria
    -: | --: | -: | --: | -: | -:
     1 | 1 | 1 | 1 | 10 | 1
     1 | 1 | 1 | 1 | 20 | 1
     2 | 2 | 2 | 2 | 10 | 2
     2 | 2 | 2 | 2 | 20 | 2
    

    db<>fique aqui

    • 21
  2. Max Szczurek
    2020-02-28T14:27:27+08:002020-02-28T14:27:27+08:00

    Você conhece essa abordagem de junção?

    SELECT *
    FROM table1, table2
    WHERE table1.pk = table2.fk
    

    Se você deixar a cláusula WHERE fora dessa consulta, obterá o produto cartesiano, que é o mesmo que um CROSS JOIN:

    SELECT *
    FROM table1
    CROSS JOIN table2
    

    Sua consulta parece combinar essa abordagem de junção com a sintaxe INNER JOIN. É logicamente igual a isto:

    SELECT *     
    FROM GLAccounts
    INNER JOIN GLCharts
        ON glaGLChartID = glcGLChartID
    LEFT JOIN GLCategories
        ON glcGLCategoryID = gltGLCategoryID
    INNER JOIN GLDepartments
        ON glaGLDepartmentID = gldGLDepartmentID
    INNER JOIN GLDivisions
        ON glaGLDivisionID = glvGLDivisionID
    CROSS JOIN GLFiscalYearPeriods                
    INNER JOIN GLFiscalYears
        ON glfGLFiscalYearID = glzGLFiscalYearID
    

    Aqui está um exemplo:

    DECLARE @t1 TABLE (t1id INT)
    DECLARE @t2 TABLE (t2id INT, t1id INT)
    DECLARE @t3 TABLE (t3id INT)
    
    INSERT INTO @t1 VALUES (1), (2)
    INSERT INTO @t2 VALUES (1, 1), (2, 1), (3, 2), (4, 2)
    INSERT INTO @t3 VALUES (5), (6)
    
    SELECT * 
    FROM @t1 
    INNER JOIN @t2 ON [@t2].t1id = [@t1].t1id
    , @t3   
    

    Devoluções:

    t1id    t2id    t1id    t3id
    1       1       1       5
    1       1       1       6
    1       2       1       5
    1       2       1       6
    2       3       2       5
    2       3       2       6
    2       4       2       5
    2       4       2       6
    
    • 7
  3. HandyD
    2020-02-28T14:19:37+08:002020-02-28T14:19:37+08:00

    A sintaxe de vírgula para a junção é uma sintaxe mais antiga no padrão ANSI SQL (SQL-89 eu acho, mas posso estar errado) que foi atualizado posteriormente (SQL-92 eu acho, novamente pode estar errado) para usar uma sintaxe mais explícita que também ficou mais legível. É conhecido como 'notação de junção implícita', em contraste com as cláusulas JOIN reais que são 'notação de junção explícita'.

    A sintaxe de vírgula implica uma junção implícita em vez de uma junção explícita, por exemplo, em seu código de exemplo sem uma cláusula WHERE, a sintaxe de vírgula implica um CROSS JOIN para produzir um produto cartesiano de todas as linhas em ambos os lados do JOIN.

    No padrão SQL preferencial, você usaria uma cláusula CROSS JOIN de notação explícita para produzir o JOIN.

    Links:

    Junte-se (SQL)

    Como faço um JOIN na sintaxe ANSI SQL 89?

    • 5

relate perguntas

  • SQL Server - Como as páginas de dados são armazenadas ao usar um índice clusterizado

  • Preciso de índices separados para cada tipo de consulta ou um índice de várias colunas funcionará?

  • Quando devo usar uma restrição exclusiva em vez de um índice exclusivo?

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

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

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