13

以下の例の「event_name」に到達するために2つのLEFTJOINを実行すると、重複が発生します。このように設定すると、112のケースが発生します。ただし、2つのLEFT JOIN行を削除してクエリを実行すると、重複のない適切な100レコードが取得されます。以下のコードでDISTINCTを試しましたが、重複して112を取得します。

SELECT "cases"."id", "cases"."date", "cases"."name", "event"."event_name" 
FROM "cases"
LEFT JOIN "middle_table" ON "cases"."serial" = "middle_table"."m_serial"
LEFT JOIN "event" ON "middle_table"."e_serial" = "event"."ev_serial"
WHERE "cases"."date" BETWEEN '2012-12-11' AND '2012-12-13'

「cases」から正確に100個のcaseのみが必要であり、結合内のテーブルからこれ以上行を生成しないように指定するにはどうすればよいですか?

ありがとう!

4

3 に答える 3

9

ON句を拡張して条件を含める必要があります。これにより、の各エントリに対して、条件に一致するcasesエントリが1つだけになり、の各エントリに対して、次のエントリが1つだけになります。middle_tablemiddle_tableevent

LEFT JOIN middle_table ON cases.serial = middle_table.m_serial AND some_condition

もちろん、DISTINCTを使用することもできます。それが機能しない場合は、、、、およびのフィールドで結果がすべて異なることを意味しcases.idます。結果を調べて、破棄するエントリを決定し、その条件をON句に含めます。cases.datecases.nameevent.event_name

于 2012-12-19T00:46:09.230 に答える
8

問題は、結合したままのテーブルに複数の一致があることです。事実上、あなたのコードは次のように言っています:

select *
from parent
left outer join child on parent.id = child.parentId

親に2人の子供がいる場合は、両方を取得します。したがって、親は2回表示されます。

妥協する必要がある場合にのみ親を取得したい場合。両方の子供を持つことはできません。子テーブルの列に対して集計関数を実行し、親テーブルの列に対してgroup byを実行するか、次のようrownumber() over partition by (list,of,parent,columns order by list,of,child,columns) rに内部ステートメントとwhere r=1外部ステートメントで使用します。

select p.id, p.name, max(c.id), max(c.name) --nb: child id and name may come from different records
from parent p
left outer join child c on parent.id = child.parentId
group by p.id, p.name

また

select *
from 
(
    select p.id, p.name, c.id, c.name
    , rownumber() over (partition by p.id order by c.id desc) r
    from parent p
    left outer join child c on parent.id = child.parentId
) x
where x.r = 1

アップデート

コメントで述べたように、子データがまったく同じである場合は、次のようにすることができます。

select p.id, p.name, c.name
from parent p
left outer join 
(
    select distinct c.parentId, c.name
    from child
) c on parent.id = child.parentId

または(いくつかのフィールドが異なるが、どちらを取得してもかまわない場合)

select p.id, p.name, c.id, c.name
from parent p
left outer join 
(
    select max(c.id) id, c.parentId, c.name
    from child
    group by c.parentId, c.name
) c on parent.id = child.parentId
于 2012-12-19T00:51:34.837 に答える
1

重複は、「middle_table」に複数のフィールドがあり、「cases」に「event」がある結果です。次のように、「GROUP BY」キーワード(通常、COUNTやSUMなどの関数の照合に使用されます)を使用して、選択を一意の値に制限できます。

SELECT "cases"."id", "cases"."date", "cases"."name", "event"."event_name" 
FROM "cases"
LEFT JOIN "middle_table" ON "cases"."serial" = "middle_table"."m_serial"
LEFT JOIN "event" ON "middle_table"."e_serial" = "event"."ev_serial"
GROUP BY  "cases"."id", "cases"."date", "cases"."name", "event"."event_name" 
WHERE "cases"."date" BETWEEN '2012-12-11' AND '2012-12-13'
于 2012-12-19T01:56:55.137 に答える