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

试试这个(如果我正确理解你的意图,你想过滤 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 对应的 location_id 的行。然后,您只需过滤掉 location_hours.type_id 的 NULL 值。

于 2013-10-23T23:22:01.643 回答