1つのmaster
テーブルがあり、これには複数のレベル(親と子)に格納されたアイテムがあり、追加のデータがある場合とない場合がある2番目のテーブルがあります。マスターテーブルから2つのレベルをクエリし、2番目のテーブルで左結合を行う必要がありますが、クエリ内の順序のためにこれは機能しません。
SELECT something FROM master as parent, master as child
LEFT JOIN second as parentdata ON parent.secondary_id = parentdata.id
LEFT JOIN second as childdata ON child.secondary_id = childdata.id
WHERE parent.id = child.parent_id AND parent.parent_id = 'rootID'
左結合は、from句の最後のテーブルでのみ機能するため、左結合の1つに対してのみ機能させることができます。上記の例では、最初の左結合がfrom句の最初のテーブルを指しているため、左結合は機能しません。2番目の結合はこのように機能しません。
どうすればこの作品を作ることができますか?
この種のクエリは動作するはずです-明示的なANSI JOIN
構文で書き直した後:
SELECT something
FROM master parent
JOIN master child ON child.parent_id = parent.id
LEFT JOIN second parentdata ON parentdata.id = parent.secondary_id
LEFT JOIN second childdata ON childdata.id = child.secondary_id
WHERE parent.parent_id = 'rootID'
ここでのつまずきは、明示的なJOIN
が「古いスタイル」CROSS JOIN
コンマ付き(,
)。 ここにマニュアルを引用します:
いずれにしても、
JOIN
は、FROM
- list項目を区切るコンマよりも強くバインドします。
最初のものを書き直した後、すべての結合が左から右に適用され(論理的には、Postgresはクエリプランのテーブルを自由に再配置できます)、機能します。
私の主張をするために、これも機能します:
SELECT something
FROM master parent
LEFT JOIN second parentdata ON parentdata.id = parent.secondary_id
, master child
LEFT JOIN second childdata ON childdata.id = child.secondary_id
WHERE child.parent_id = parent.id
AND parent.parent_id = 'rootID'
ただし、ケースでもう一度説明するように、一般的には明示的なJOIN
構文が望ましいです。
また、複数(左)のJOINで行を乗算できることに注意してください。
このようにすることができます
SELECT something
FROM
(a LEFT JOIN b ON a.a_id = b.b_id) LEFT JOIN c on a.a_aid = c.c_id
WHERE a.parent_id = 'rootID'
JOIN
ステートメントはFROM
句の一部でもあり、より正式にはjoin_typeを使用して2つfrom_item 's into onefrom_item -FROM
の後に区切られたリスト。 http://www.postgresql.org/docs/9.1/static/sql-select.html を参照してください。
あなたの問題の直接的な解決策は次のとおりです。
SELECT something
FROM
master as parent LEFT JOIN second as parentdata
ON parent.secondary_id = parentdata.id,
master as child LEFT JOIN second as childdata
ON child.secondary_id = childdata.id
WHERE parent.id = child.parent_id AND parent.parent_id = 'rootID'
すでに提案されているように、JOIN
のみを使用することをお勧めします。