Was bedeutet [FROM x, y] in Postgres?


12

Ich fange gerade erst mit Postgres an. Beim Lesen dieses Dokuments bin ich auf folgende Abfrage gestoßen:

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;

Ich kann alles in dieser Abfrage verstehen , außer diesem: FROM apod, ....

Was bedeutet dies ,bedeuten? Ich bin es gewohnt, mich zusammenzufügen, aber nicht an mehrere FROMAnweisungen, die durch ein Komma getrennt sind.

Ich suchte im Netz ohne Erfolg. Nachdem ich es mir angeschaut und überlegt habe, scheint es mir, dass es eine Variable namens query deklariert, damit es mehrmals verwendet werden kann. Aber wenn das stimmt, was hat es damit zu tun FROM?

Antworten:


10

Es entsteht ein Implizit CROSS JOIN. Es ist die SQL-89-Syntax.

Hier benutze values(1)und values(2)erstelle ich pseduo-Tabellen (Wertetabellen) nur als Beispiel. Die Sache nach ihnen t(x), und g(y)wird als FROM-Aliases der Zeichen in der Klammer ist der Alias für die Spalte ( xund yjeweils). Sie könnten genauso einfach eine Tabelle erstellen, um dies zu testen.

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

So würden Sie es jetzt schreiben.

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

Von dort aus können Sie dies implizit machen, INNER JOINindem Sie eine Bedingung hinzufügen.

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

Oder die explizite und neuere INNER JOINSyntax,

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

Also in deinem Beispiel ..

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

Dies entspricht im Wesentlichen der neueren Syntax.

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

Das ist in diesem Fall eigentlich das Gleiche, weil to_tsquery()eine Zeile und keine Menge zurückgegeben wird als:

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;

Dies kann möglicherweise to_tsquery('neutrino|(dark & matter)')zu zweimaligem Auftreten führen. In diesem Fall ist dies jedoch nicht der Fall - und to_tsquerywird als STABLE (verifiziert mit \dfS+ to_tsquery) gekennzeichnet.

STABLEGibt an, dass die Funktion die Datenbank nicht ändern kann und dass sie innerhalb eines einzelnen Tabellenscans konsistent dasselbe Ergebnis für dieselben Argumentwerte zurückgibt, das Ergebnis sich jedoch über SQL-Anweisungen hinweg ändern kann. Dies ist die geeignete Auswahl für Funktionen, deren Ergebnisse von Datenbanksuchen, Parametervariablen (wie der aktuellen Zeitzone) usw. abhängen Die Funktionsfamilie current_timestamp gilt als stabil, da sich ihre Werte innerhalb einer Transaktion nicht ändern.

Für einen vollständigeren Vergleich der Unterschiede zwischen SQL-89 und SQL-92 siehe auch meine Antwort hier


Vielen Dank. Ich fange gerade mit SQL an. Es ist sinnvoll ,, eine Kreuzverknüpfung zu erstellen, da es sich nur um ein kartesisches Produkt handelt und kein Vergleich erforderlich ist. Können Sie nur noch eine Frage beantworten, BITTE? was ist t(x)in (values(1)) AS t(x)???
Andrerpena

@andrerpena aktualisiert.
Evan Carroll

1
Du bist der beste. Kristallklare Erklärung. Danke vielmals.
Andrerpena

Nie den Begriff "FROM-Alias" für einen Tabellenalias gehört . to_tsquery()gibt einen Wert zurück, keine Zeile . Und nur weil eine Funktion definiert ist STABLE, das bedeutet nicht , die Abfrage Planer werden wiederholte Auswertung vermeiden. Es kann .
Erwin Brandstetter

12

Das Handbuch enthält eine detaillierte Erklärung für das Komma in der FROMListe im Kapitel Tabellenausdrücke :

Die FROMKlausel leitet eine Tabelle von einer oder mehreren anderen Tabellen ab, die in einer durch Kommas getrennten Tabellenreferenzliste angegeben sind.

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

Eine Tabellenreferenz kann ein Tabellenname (möglicherweise schemaqualifiziert) oder eine abgeleitete Tabelle wie eine Unterabfrage, ein JOINKonstrukt oder komplexe Kombinationen davon sein. Wenn in der FROMKlausel mehr als eine Tabellenreferenz aufgeführt ist, werden die Tabellen miteinander verknüpft (dh das kartesische Produkt ihrer Zeilen wird gebildet; siehe unten).

Die Tatsache , dass durch Kommata getrennte Tabellenverweise haben in einer früheren Version der SQL - Standards als explizit definiert wurden JOINSyntax nicht nicht das Komma falsch oder veraltet machen. Verwenden Sie eine explizite Join-Syntax, wenn dies technisch erforderlich ist (siehe unten) oder der Abfragetext klarer wird.

Das Handbuch nochmal:

FROM T1 CROSS JOIN T2entspricht FROM T1 INNER JOIN T2 ON TRUE (siehe unten). Es ist auch äquivalent zu FROM T1, T2.

"Äquivalent" heißt aber nicht identisch . Es gibt einen subtilen Unterschied, wie das Handbuch feststellt :

Hinweis:
Diese letztere Entsprechung gilt nicht genau, wenn mehr als zwei Tabellen angezeigt werden, da die JOINBindung enger als das Komma ist. Zum Beispiel FROM T1 CROSS JOIN T2 INNER JOIN T3 ON conditionist das nicht dasselbe wie, FROM T1, T2 INNER JOIN T3 ON conditionweil das im ersten Fall conditionreferenzieren kann, T1aber nicht im zweiten.

Diese verwandte Frage zeigt die Relevanz des Unterschieds:

Grundsätzlich ist Ihre Beobachtung genau richtig:

es scheint mir, dass es eine Variable namens query deklariert, so dass es mehrere Male verwendet werden kann.

Jede Funktion kann als "Tabellenfunktion" in der FROMListe verwendet werden. Und Funktionsparameter können auf Spalten aus allen Tabellen links von der Funktion verweisen, da die Notation:

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

ist wirklich äquivalent zu:

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

Das Handbuch zu LATERAL-Abfragen:

In Tabellenfunktionen FROMkann auch das Schlüsselwort vorangestellt werden. LATERALBei Funktionen ist das Schlüsselwort jedoch optional . Die Argumente der Funktion können in jedem Fall Verweise auf Spalten enthalten, die durch vorangestellte FROM-Elemente bereitgestellt werden.

Meine kühne Betonung.

Das SchlüsselwortAS ist vollständig optionales Rauschen vor Tabellenaliasen (im Gegensatz zu Spaltenaliasen , bei denen empfohlen wird, es nicht auszulassen AS, um mögliche Mehrdeutigkeiten zu vermeiden). Verwandte Antwort mit mehr:

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.