9

デザインのリストが必要な左結合に少し問題があり、各デザインに各デザインのコメント数を表示したい.

LEFT JOIN を使用しています

SELECT ds.*, count(com.comment) AS countcom FROM tdic_designs ds 
LEFT JOIN tdic_comments com ON (com.design_id = ds.id) 
WHERE ds.approved = 1 AND ds.hidden = 0 AND com.approved = 1 
GROUP BY ds.id 
ORDER BY ds.date_added ASC

しかし、コメントが 1 つある 1 つのデザインしか表示されないため、これは機能しませんが、テーブルには 2 つのデザインがあり、2 つ目のデザインにはコメントがありません。

SQLを次のように変更すると

SELECT ds.*, count(com.comment) AS countcom FROM tdic_designs ds 
LEFT JOIN tdic_comments com ON (com.design_id = ds.id) 
GROUP BY ds.id, com.approved, ds.approved 
ORDER BY ds.date_added ASC

つまり、WHERE 句を削除しています。しかし、承認されていないデザインとコメントの両方が選択されるため、これは悪いことです。

私が見逃している/間違っていることは何ですか?

4

3 に答える 3

22

コメントのすべてのフィルターをON句に移動します。

SELECT  ds.*, COUNT(com.design_id) AS countcom
FROM    tdic_designs ds
LEFT JOIN
        tdic_comments com
ON      com.design_id = ds.id
        AND com.approved = 1 
WHERE   ds.approved = 1
        AND ds.hidden = 0
GROUP BY
        ds.id
ORDER BY
        ds.date_added ASC
于 2012-06-08T12:56:57.860 に答える
5

WHEREこの句を使用すると、これらの制限は によって提供される行に適用されleft joinます。そのため、制限に同意しない場合、一部の行が削除されます。

あなたがする必要があるのは、これらの制限をON句に入れることです。それが機能しない場合はNULL、行を削除する代わりに表示されます。

このようなもの:

SELECT ds.id, count(com.comment) AS countcom
FROM tdic_designs ds
LEFT JOIN tdic_comments com ON (com.design_id = ds.id) AND ds.approved = 1 AND ds.hidden = 0 AND com.approved = 1
GROUP BY ds.id
ORDER BY ds.date_added ASC

もう 1 つの問題は、 だけを持っているときに を使用することds.*です。SELECTds.idgroup BY

于 2012-06-08T12:57:29.637 に答える
1

問題はcom.approved = 1、WHERE 句に含めると、ある行が除外されることcom.approvedですNULL。つまり、外部テーブルで一致が見つからなかったすべての行が除外されます。

他の人が示唆しているように、その条件をON句に移動することでこれを修正できますが、それは結合条件ではないため、あまり好きではありません。

外側のテーブルのフィルターをインライン ビューに移動します。

SELECT ds.*, count(com.comment) AS countcom FROM tdic_designs ds 
LEFT JOIN (SELECT * FROM tdic_comments com WHERE com.approved = 1) com
ON (com.design_id = ds.id) 
WHERE ds.approved = 1 AND ds.hidden = 0 
GROUP BY ds.id 
ORDER BY ds.date_added ASC
于 2012-06-08T13:04:00.320 に答える