Che cosa significa [DA x, y] in Postgres?


12

Ho appena iniziato con Postgres. Leggendo questo documento mi sono imbattuto in questa domanda:

SELECT title, ts_rank_cd(textsearch, query) AS rank
FROM apod, to_tsquery('neutrino|(dark & matter)') query
WHERE query @@ textsearch
ORDER BY rank DESC
LIMIT 10;

Posso capire tutto in questa query, tranne che per questo: FROM apod, ....

Cosa significa questo ,? Sono abituato a unirmi ma non a più FROMistruzioni separate da una virgola.

Ho cercato in rete senza alcun risultato. Dopo averlo guardato e pensato, mi sembra che stia dichiarando una variabile chiamata query in modo che possa usarla più volte. Ma se questo è vero, cosa c'entra FROM?

Risposte:


10

Crea un implicito CROSS JOIN. È la sintassi SQL-89.

Qui uso values(1)e values(2)creo tabelle pseduo (tabelle di valori) solo per esempi. La cosa dopo di loro t(x), e g(y)sono chiamati FROM-Alias, il carattere all'interno della parentesi è l'alias per la colonna ( xe yrispettivamente). È possibile creare altrettanto facilmente una tabella per verificarlo.

SELECT *
FROM (values(1)) AS t(x), (values(2)) AS g(y)

Ecco come lo scriveresti ora.

SELECT *
FROM (values(1)) AS t(x)
CROSS JOIN (values(2)) AS g(y);

Da lì puoi renderlo implicito INNER JOINaggiungendo un condizionale.

SELECT *
FROM (values(1)) AS t(x)
CROSS JOIN (values(1)) AS g(z)
WHERE x = z;

O la INNER JOINsintassi esplicita e più recente ,

SELECT *
FROM (values(1)) AS t(x)
INNER JOIN (values(1)) AS g(z)
  ON ( x = z );

Quindi nel tuo esempio ..

FROM apod, to_tsquery('neutrino|(dark & matter)') query

Questo è essenzialmente lo stesso della sintassi più recente,

FROM apod
CROSS JOIN to_tsquery('neutrino|(dark & matter)') AS query

che in realtà è lo stesso, in questo caso, perché to_tsquery()restituisce una riga e non un set come,

SELECT title, ts_rank_cd(
  textsearch,
  to_tsquery('neutrino|(dark & matter)')
) AS rank
FROM apod
WHERE to_tsquery('neutrino|(dark & matter)') @@ textsearch
ORDER BY rank DESC
LIMIT 10;

Tuttavia, quanto sopra potrebbe potenzialmente to_tsquery('neutrino|(dark & matter)')verificarsi due volte, ma in questo caso non to_tsqueryè - è contrassegnato come STABILE (verificato con \dfS+ to_tsquery).

STABLEindica che la funzione non può modificare il database e che all'interno di una singola scansione della tabella restituirà costantemente lo stesso risultato per gli stessi valori dell'argomento, ma che il suo risultato potrebbe cambiare attraverso le istruzioni SQL. Questa è la selezione appropriata per le funzioni i cui risultati dipendono dalle ricerche nel database, dalle variabili dei parametri (come il fuso orario corrente), ecc. (È inappropriato per i trigger AFTER che desiderano interrogare le righe modificate dal comando corrente.) Si noti inoltre che il La famiglia di funzioni current_timestamp si qualifica come stabile, poiché i loro valori non cambiano all'interno di una transazione.

Per un confronto più completo delle differenze tra SQL-89 e SQL-92, vedere anche la mia risposta qui


Grazie mille. Sto solo iniziando con SQL. È logico ,che si tratti di un cross join in quanto è solo un prodotto cartesiano e non sono previsti confronti. Puoi rispondere ad un'altra domanda PER FAVORE? cosa c'è t(x)dentro (values(1)) AS t(x)???
andrerpena,

@andrerpena aggiornato.
Evan Carroll,

1
sei il migliore. Spiegazione cristallina. Grazie mille.
andrerpena,

Non ho mai sentito il termine "DAL alias" per un alias di tabella . to_tsquery()restituisce un valore non una riga . E solo perché una funzione è definita STABLE, che non significa il pianificatore di query sarà evitare la valutazione ripetuta. Si può .
Erwin Brandstetter,

12

Il manuale contiene spiegazioni dettagliate per la virgola FROMnell'elenco nel capitolo Espressioni tabella :

La FROMclausola deriva una tabella da una o più altre tabelle fornite in un elenco di riferimento di tabella separato da virgole.

FROM table_reference [, table_reference [, ...]]

Un riferimento a una tabella può essere un nome di tabella (possibilmente qualificato da schema) o una tabella derivata come una sottoquery, un JOINcostrutto o combinazioni complesse di questi. Se nella FROMclausola è elencato più di un riferimento di tabella , le tabelle sono unite tra loro (ovvero, si forma il prodotto cartesiano delle loro righe; vedere di seguito).

Il fatto che i riferimenti di tabella separati da virgola siano stati definiti in una versione precedente dello standard SQL rispetto alla JOINsintassi esplicita non rende la virgola errata o obsoleta. Utilizzare la sintassi del join esplicito, dove è tecnicamente necessario (vedere di seguito) o dove rende più chiaro il testo della query.

Il manuale di nuovo:

FROM T1 CROSS JOIN T2è equivalente a FROM T1 INNER JOIN T2 ON TRUE (vedi sotto). È anche equivalente a FROM T1, T2.

Ma "equivalente" non significa identico . C'è una sottile differenza, come nota il manuale :

Nota
Quest'ultima equivalenza non vale esattamente quando compaiono più di due tabelle, perché si JOINlega più strettamente della virgola. Ad esempio FROM T1 CROSS JOIN T2 INNER JOIN T3 ON conditionnon è lo stesso di FROM T1, T2 INNER JOIN T3 ON conditionperché conditionpuò fare riferimento T1nel primo caso ma non nel secondo.

Questa domanda correlata dimostra la rilevanza della differenza:

Fondamentalmente, la tua osservazione è esattamente corretta:

mi sembra che stia dichiarando una variabile chiamata query in modo che possa usarla più volte.

Qualsiasi funzione può essere utilizzata come "funzione tabella" FROMnell'elenco. E i parametri della funzione possono fare riferimento a colonne da tutte le tabelle a sinistra della funzione, poiché la notazione:

FROM apod, to_tsquery('neutrino|(dark & matter)') query

è davvero equivalente a:

FROM apod CROSS JOIN LATERAL to_tsquery('neutrino|(dark & matter)') AS query

Il manuale sulle query LATERAL:

Le funzioni di tabella che compaiono in FROMpossono anche essere precedute dalla parola chiave LATERAL, ma per le funzioni la parola chiave è facoltativa ; gli argomenti della funzione possono contenere riferimenti a colonne fornite precedendo gli elementi FROM in ogni caso.

Enorme enfasi sulla mia.

La parola chiaveAS è rumore completamente opzionale prima degli alias di tabella (al contrario degli alias di colonna , dove si consiglia di non omettere ASper evitare possibili ambiguità). Risposta correlata con altro:

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.