[FROM x、y]はPostgresで何を意味しますか?


12

Postgresを始めたばかりです。このドキュメントを読んで私はこのクエリに出会いました:

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;

これを除く、このクエリのすべてを理解できます。FROM apod, ...

これは,どういう意味ですか?私は参加するのに慣れていますが、複数ではありませんFROM、コンマで区切られたステートメント。

私は、ネットを検索しました。それを見て考えた後、クエリと呼ばれる変数を宣言しているので、複数回使用できるように思えます。しかし、これが本当なら、それは何と関係がありFROMますか?

回答:


10

暗黙的なを作成しCROSS JOINます。SQL-89構文です。

ここではvalues(1)values(2)単に例としてpseduo-table(値テーブル)を使用して作成しています。それらの後の事t(x)、とg(y)呼ばれているFROM-別名括弧内の文字列(の別名であるxy、それぞれ)。これをテストするためのテーブルを簡単に作成できます。

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

ここにあなたが今それを書く方法があります。

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

そこからINNER JOIN条件を追加することでこれを暗黙的にすることができます。

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

または、明示的で新しいINNER JOIN構文、

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

あなたの例では..

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

これは基本的に新しい構文と同じですが、

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

実際には同じです。この場合、to_tsquery()セットではなく行を返すため、

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;

ただし、上記は潜在的にto_tsquery('neutrino|(dark & matter)')2回発生する可能性がありますが、この場合は発生しません-STABLE(で検証済み)to_tsqueryとしてマークされます。\dfS+ to_tsquery

STABLE関数はデータベースを変更できず、単一のテーブルスキャン内で同じ引数値に対して一貫して同じ結果を返しますが、その結果はSQLステートメント間で変わる可能性があることを示します。これは、結果がデータベースルックアップ、パラメーター変数(現在のタイムゾーンなど)などに依存する関数に適した選択です(現在のコマンドで変更された行を照会するAFTERトリガーには不適切です)。関数のcurrent_timestampファミリは、値がトランザクション内で変化しないため、安定していると見なされます。

SQL-89とSQL-92の違いのより完全な比較については、こちらの回答も参照してください。


どうもありがとうございました。私はSQLから始めています。,デカルト積であり、比較は含まれていないため、クロス結合であることが理にかなっています。もう1つ質問してください。何t(x)(values(1)) AS t(x)
アンドレペナ

@andrerpenaが更新されました。
エヴァンキャロル

1
あなたは最高です。明確な説明。トンありがとう。
アンドレペナ

テーブルエイリアスの「FROMエイリアス」という用語を聞いたことがない。rowではなく値をto_tsquery()返します。また、関数が定義されているからといって、クエリプランナー繰り返し評価避けられるわけではありません。それはすることができますSTABLE
アーウィンブランドステッター

12

マニュアルには、テーブル式の章FROMリストにあるカンマの詳細な説明があります

このFROM句は、カンマ区切りのテーブル参照リストで指定された1つ以上の他のテーブルからテーブルを派生します。

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

テーブル参照は、テーブル名(スキーマで修飾されている場合もあります)、またはサブクエリ、JOIN構造、またはこれらの複雑な組み合わせなどの派生テーブルです。FROM句に複数のテーブル参照がリストされている場合、テーブルは相互結合されます(つまり、行のデカルト積が形成されます。以下を参照)。

明示的なJOIN構文よりも前のバージョンのSQL標準では、コンマ区切りのテーブル参照が定義されているという事実はによって、コンマが間違ったり、古くなったりすることはあり。明示的に結合構文を使用します。技術的に必要な場合(以下を参照)、またはクエリテキストを明確にする場合。

再びマニュアル:

FROM T1 CROSS JOIN T2と同等ですFROM T1 INNER JOIN T2 ON TRUE (以下を参照)。また、と同等FROM T1, T2です。

しかし、「同等」同一を意味しませんマニュアルに記載されているように、微妙な違いがあります


この後者の同等性はJOIN、コンマよりも強くバインドするため、3つ以上のテーブルが表示される場合には正確に保持されません。たとえば、 FROM T1 CROSS JOIN T2 INNER JOIN T3 ON condition同じではない FROM T1, T2 INNER JOIN T3 ON conditionため、condition缶参照T1最初のケースではなく、第二。

この関連する質問は、違いの関連性を示しています。

基本的に、あなたの観察は正確です:

複数回使用できるようにqueryという変数を宣言しているように思えます。

FROMリスト内の「テーブル関数」として任意の関数を使用できます。また、関数のパラメーターは、関数の左側にあるすべてのテーブルの列を参照できます。

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

本当に同等です:

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

LATERALクエリに関するマニュアル:

に表示されるテーブル関数のFROM前にキーワードを置くこともできます LATERALが、関数の場合、キーワードはオプションです。関数の引数には、どのような場合でも先行するFROMアイテムによって提供される列への参照を含めることができます。

大胆な強調鉱山。

キーワードはAS前に完全に任意のノイズであるテーブルの別名(とは対照的に、列の別名省略していないお勧めします、AS可能なあいまいさを避けるため)。さらに関連する回答:

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.