14

JOIN ステートメントでサブクエリを使用して、かなり単純なクエリを作成しています。サブクエリの選択に * を含めた場合にのみ機能します。なんで?

これは機能します

$sql = 'SELECT locations.id, title, name, hours.lobby
        FROM locations
        LEFT JOIN states ON states.id = locations.state_id
        LEFT JOIN (SELECT *, type_id IS NOT NULL AS lobby FROM location_hours) AS hours ON locations.id = hours.location_id
        GROUP BY locations.id';

これはしません

$sql = 'SELECT locations.id, title, name, hours.lobby
        FROM locations
        LEFT JOIN states ON states.id = locations.state_id
        LEFT JOIN (SELECT type_id IS NOT NULL AS lobby FROM location_hours) AS hours ON locations.id = hours.location_id
        GROUP BY locations.id';

私もこのようにすべきですか?すべてのフィールドが必要ない場合、* は最適ではないと思いましたか?

4

2 に答える 2

47

これを試してください(あなたの意図を正しく理解していれば、nullではなくtype_idでフィルタリングしたかったのです):

   SELECT locations.id, title, name, hours.lobby
     FROM locations
LEFT JOIN states
       ON states.id = locations.state_id
LEFT JOIN (SELECT location_id, type_id AS lobby
             FROM location_hours 
            WHERE type_id IS NOT NULL) AS hours
       ON locations.id = hours.location_id
 GROUP BY locations.id';

説明は、外側のクエリで参照されるすべてのフィールドを内側のクエリで選択する必要があるということです。

于 2013-10-23T23:10:58.227 に答える
0

type_id には NULL 以外の値が必要なため、LEFT JOIN をまったく使用しないでください。標準の JOIN を使用する次のものが必要になります。

$sql = 'SELECT locations.id, title, name, location_hours.type_id
        FROM locations
        JOIN location_hours ON location_hours.location_id = locations.id
        LEFT JOIN states ON states.id = locations.state_id
        WHERE location_hours.type_id IS NOT NULL
        GROUP BY locations.id';

JOIN の要点は、実際に存在する行のみを結合することです。したがって、location_hours に対応する location_id が locations.id にない行は取得されません。次に、location_hours.type_id の NULL 値を除外します。

于 2013-10-23T23:22:01.643 に答える