所以我需要在人员表中列出所有人。每行都有一个office_id
,当某人被分配到办公室时,它包含一个大于 0 的值,我需要在办公室表中查找该值以获取分配给该人的办公室的名称。但是当我使用INNER JOIN
时,它会忽略office_id = 0
的记录。
SELECT *
FROM personnel
WHERE building_id=$SESSION[building_id]
ORDER BY last_name
INNER JOIN offices
WHERE offices.office_id=personnel.office_id
现在,它给了我所有有指定办公室的人,但忽略了那些没有指定办公室的人(吉尔)。我怎样才能让它们都如下所示:
Jack Building1 Office1<br>
John Building1 Office2<br>
Jill Building1 <br>
Judy Building1 Office3<br>
Jenn Building1 Office4<br>
我按照正确的语句顺序排列了 SQL,并注释了如果使用其他语句的位置,并将 WHERE 切换到 LEFT 连接的 on 子句,该子句将包括所有人员和仅匹配的办公室中的记录。
SELECT *
FROM personnel p
LEFT JOIN offices o
ON o.office_id=p.office_id
-- and o.building_id=$SESSION[building_id] --this if building is in offices. and eliminate next
WHERE building_id=$SESSION[building_id]
-- GROUP BY
-- HAVING
ORDER BY p.last_name
-- LIMIT
请注意,当使用多个表时,明智的做法是将所涉及的表和 完全限定字段,因此哪一列来自哪个表不会产生歧义。
这很重要,因为:building_Id在什么表中?
如果是办公室,那么我们可能不得不从整体上消除 where 子句,并在连接上有一个"AND"。 否则,where 子句将否定左连接,使其行为类似于内部连接。
为什么。。。联接首先为某些人员创建具有空building_ID的办公室。 然后,where 子句运行,消除 NULL 记录,因为它们与 $Session 不匹配[Building_ID]。 所以我们只是把左边的加入行为做成一个内部的,如果建筑物在办公室的桌子上。
现在,如果建筑物在人事桌上....那么没关系,把它留在 where 子句中就可以了。
对于您的任务,您应该使用LEFT JOIN
它将返回下表。LEFT JOIN
获取左侧的内容(人员)并连接右侧的内容(办公室),如果左侧表中的记录没有对,那么它将只返回缺少值的 Null。
SELECT *
FROM personnel
LEFT JOIN offices ON offices.office_id=personnel.office_id
WHERE building_id=$SESSION[building_id]
ORDER BY last_name
|Jack | Building1 | Office1
|John | Building1 | Office2
|Jill | Building1 | Null
|Judy | Building1 | Office3
|Jenn | Building1 | Office4
还要确保使用正确的 SQL 运算符序列:选择 ...从。。。[左/右加入...上...]哪里。。。分组依据 ...