2013-01-10 9 views
18

複数のレベル、親と子に格納されたアイテムを持つmasterテーブルが1つあり、追加データがある場合とない場合がある2番目のテーブルがあります。私は私のマスターテーブルから2つのレベルをクエリし、私の2番目のテーブルに左の結合を持っている必要がありますが、私のクエリ内の順序のため、これは動作しません。1つのクエリで複数のテーブルに複数の左結合があります

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句の最後の表としか機能しないため、左結合のいずれかでのみ機能するようにすることができます。上の例では、最初の左の結合がfrom節の最初のテーブルを指しているため、左の結合のいずれも機能しません。

どうすればこの作品を作成できますか?

+6

のように行うことができます...ON)はほとんど涙が止まらない。それを書き直して、あなたが本当に排除したくない行を排除している可能性のあるWHERE節を見てみましょう。 –

答えて

29

クエリのこの種の作業をする必要があります - 明示的な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

I quote the manual here: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構文は、一般的に好ましいです。

と複数(LEFT)が行掛けることができます参加することに注意してください:

2

JOIN文もFROM句の一部であり、より正式join_typeをするために使用されますが2つを組み合わせるfrom_itemを1つにまとめるfrom_item複数の1つをカンマ区切りのリストにすることができますr FROMhttp://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年代を用いることであろう。

4

あなたは「新しいスタイル」と「古いスタイル」(2人のテーブル名FROM句中)(LEFT 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' 
+3

@DeniseMeander:なぜこの答えが受け入れられるのかわかりません。古い質問には何も追加されません。括弧は例外ですが、この場合はノイズだけです。そして説明もありません。明示的な結合は、デフォルトで左から右へ実行されます(結合条件が異なる順序を強制しない限り)。 –

+0

@ErwinBrandstetterこの答えはより明確です。テーブルの名前にスペースが含まれているため、混乱します。 – kahonmlg

+1

@kahonmlg:テーブル名にスペースはありません。たぶん、あなたはテーブルエイリアスを誤解しているかもしれません。参照:https://stackoverflow.com/a/11543614/939860 –

関連する問題