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 / 343949
Accepted
J. Mini
J. Mini
Asked: 2024-12-01 23:30:55 +0800 CST2024-12-01 23:30:55 +0800 CST 2024-12-01 23:30:55 +0800 CST

Se LATERAL é opcional para funções com valor de tabela, então por que essa consulta gera erro sem ele?

  • 772

Configurar

CREATE TABLE persons
(
  person_id int not null,
  name TEXT 
);

INSERT INTO persons VALUES
(1, 'Adam'),
(2, 'Paul'),
(3, 'Tye'),
(4, 'Sarah');

CREATE TABLE json_to_parse
(
  person_id int not null,
  block json
);

INSERT INTO json_to_parse VALUES
  (1, '{"size": "small", "love": "x"}'),
  (2, '{"size": "medium", "love": "xx"}'),
  (3, '{"size": "big", "love": "xxx"}');

O erro

Isso funciona sem problemas

SELECT
  *
FROM
  json_to_parse
CROSS JOIN LATERAL
  json_to_record(json_to_parse.block) AS my_json(size TEXT, love TEXT)
INNER JOIN
  persons
ON
  persons.person_id = json_to_parse.person_id;

mas isso não

SELECT
  *
FROM
  json_to_parse,
  json_to_record(json_to_parse.block) AS my_json(size TEXT, love TEXT)
INNER JOIN
  persons
ON
  persons.person_id = json_to_parse.person_id;

e recebo o erro "referência inválida para a entrada da cláusula FROM para a tabela "json_to_parse""

Por que esse segundo erro de consulta? Os documentos deixam bem claro que LATERALé opcional para funções com valor de tabela

As funções de tabela que aparecem em FROMtambém podem ser precedidas pela palavra-chave LATERAL, mas para funções a palavra-chave é opcional; os argumentos da função podem conter referências a colunas fornecidas pelos FROMitens precedentes em qualquer caso.

dbfiddle

postgresql
  • 2 2 respostas
  • 348 Views

2 respostas

  • Voted
  1. Best Answer
    Erwin Brandstetter
    2024-12-02T06:28:12+08:002024-12-02T06:28:12+08:00

    A palavra-chave LATERAL é sempre opcional para funções na FROMlista. Esse não é o problema na sua consulta.

    Ligações explícitas JOINmais fortes do que uma vírgula na FROMlista. Esse é o problema. Veja:

    • O que significa [FROM x, y] no Postgres?

    Sua segunda consulta está logicamente errada. json_to_record(json_to_parse.block)binds to persons antes do resultado de both seria unido com json_to_parse, o que contradiz a referência inicial a json_to_parse.block. Daí o erro.

    Não há nada de errado com vírgulas na FROMlista em si . É apenas tipicamente mais fácil de ler e manter quando você coloca a condição de junção principal entre duas tabelas na cláusula ONor USINGde a JOINonde for viável. (E faz uma diferença funcional para OUTER JOIN!). Use a vírgula livremente quando for correto e apropriado.

    Enquanto damos opiniões, é assim que eu escreveria sua consulta:

    SELECT *  -- really all columns from all tables?
    FROM   persons p
    JOIN   json_to_parse jp USING (person_id)
         , json_to_record(jp.block) AS bl(size text, love text);
    

    Ou, se preferir soletrar:

    ...
    CROSS  JOIN LATERAL json_to_record(jp.block) AS bl(size text, love text);
    
    • 6
  2. Charlieface
    2024-12-02T02:04:16+08:002024-12-02T02:04:16+08:00

    TL;DR; Não misture comma-joins com explícitas joins. Na verdade, não use comma-joins de forma alguma.

    Você tem uma vírgula-join na segunda consulta. Comma-joins são interpretadas como CROSS JOINentão você parece ter esperado que a consulta fosse interpretada da seguinte forma:

    FROM
      json_to_parse
    CROSS JOIN
      json_to_record(json_to_parse.block) AS my_json(size TEXT, love TEXT)
    INNER JOIN
      persons
    ON
      persons.person_id = json_to_parse.person_id
    

    o que realmente funciona, pois LATERALé opcional.

    Mas como as junções por vírgula têm uma precedência menor do que a sintaxe de junção explícita, o que realmente acontece é isto:

    FROM
      json_to_parse
    CROSS JOIN (
        json_to_record(json_to_parse.block) AS my_json(size TEXT, love TEXT)
        INNER JOIN
          persons
        ON
          persons.person_id = json_to_parse.person_id
    )
    

    * Eu sei que o Postgres não suporta essa sintaxe, mas outros SGBDs suportam, e você também pode usar uma subconsulta

    Já que agora você tem um tipo de subconsulta, LATERALnão é opcional. Agora deve ser óbvio por que não funciona: os parênteses implícitos estão empurrando o INNER JOIN persons... ON...para um escopo separado.

    Dos documentos :

    Uma JOINcláusula combina dois FROMitens, que por conveniência chamaremos de “tabelas”, embora na realidade possam ser qualquer tipo de FROMitem. Use parênteses se necessário para determinar a ordem de aninhamento. Na ausência de parênteses, JOINs aninha da esquerda para a direita. Em qualquer caso, JOINvincula mais firmemente do que as vírgulas que separam FROMos itens da lista.


    Junções por vírgula são velharias. Junções explícitas foram introduzidas no SQL-92, e há muito poucos casos em que é mais legível usar junções por vírgula. Favoreça sempre a sintaxe de junção explícita .

    • 2

relate perguntas

  • Posso ativar o PITR depois que o banco de dados foi usado

  • Práticas recomendadas para executar a replicação atrasada do deslocamento de tempo

  • Os procedimentos armazenados impedem a injeção de SQL?

  • Sequências Biológicas do UniProt no PostgreSQL

  • Qual é a diferença entre a replicação do PostgreSQL 9.0 e o Slony-I?

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