4

次の MySQL クエリを実行して、マニュアルがない (そして黒いホイールなどがある) 車を検索しています。

SELECT `cars`.* FROM `cars`
INNER JOIN wheels ON cars.id = wheels.car_id
LEFT OUTER JOIN manuals ON cars.id = manuals.car_id
WHERE (cars.created_at > '2010-09-09'
AND wheels.color = 'Black'
AND wheels.created_at < '2011-01-05'
AND manuals.car_id IS NULL)

クエリの結果は正しいように見えますが、ID 27 の車が 2 回返されます。すべての結果が一意 (重複なし) になるようにクエリを変更するにはどうすればよいですか?

4

3 に答える 3

15

SELECT DISTINCT代わりに試すことができますSELECT

于 2011-01-11T22:11:32.093 に答える
6

group by cars.idクエリ EG の最後に追加します。

SELECT `cars`.* FROM `cars`
INNER JOIN wheels ON cars.id = wheels.car_id
LEFT OUTER JOIN manuals ON cars.id = manuals.car_id
WHERE (cars.created_at > '2010-09-09'
    AND wheels.color = 'Black'
    AND wheels.created_at < '2011-01-05'
    AND manuals.car_id IS NULL)
GROUP BY cars.id
于 2011-01-11T22:10:10.477 に答える
3

それcars.idが一意の主キーであると仮定すると、それらの結合の 1 つがデカルト積を引き起こしています。つまり、 または に複数の一致を含む のいずれwheelsmanualsですcars.id = 27

サブクエリは、多くの場合、デカルト積を排除するための優れたツールです。次のクエリの例は、サブクエリを使用する 2 つの方法を示しています。

  1. 最初のサブクエリは、そのレコードが 2011 年 1 月 5 日より前に作成された黒い車輪の車のみを確認していることを保証します。このGROUP BY句により、 ごとに 1 つのレコードのみが返されることが保証されw.car_idます。

  2. 2 番目のサブクエリ (相関サブクエリと呼ばれることもあります) は、メイン クエリで各車のマニュアルが見つからないようにします。

テストされていませんが、アイデアを伝えます:

SELECT `cars`.* 
  FROM `cars`
       JOIN (
           SELECT w.car_id
             FROM wheels w
            WHERE w.color = 'Black'
              AND w.created_at < '2011-01-05'
         GROUP BY w.car_id
       ) wheels 
       ON cars.id = wheels.car_id
WHERE 
    cars.created_at > '2010-09-09'
AND
    NOT EXISTS (SELECT m.car_id FROM manuals m WHERE m.car_id = cars.id)
于 2011-01-11T22:32:17.197 に答える