作为我的数据库主题的每周练习,我有3个表。班级,部门和员工,我需要列出与员工和部门名称对应的班级名称。部门名称是物品所在的部门。问题是有一些员工没有住在任何部门,所以他们的列值为空。
表的主要结构:
+------------------------+
| class || staff|| dep |
+------------------------+
| A || 1 || L |
| B || 2 || G |
| C || 3 || |
| D || 4 || L |
+------------------------+
这就是我想要实现的目标。 department_name为null的工作人员必须保持为空。
SELECT DISTINCT c.name AS "class_name" , st.name AS "staff_name", d.name AS "department_name"
FROM class c, staff st, department d
WHERE c.staffid = st.staffid AND st.deptid = d.deptid
UNION
SELECT DISTINCT class.name AS "class_name", staff.name AS "staff_name" , NULL AS "department_name" FROM staff staff, class class, department d WHERE staff.deptid IS NULL AND staff.staffid = class.staffid;
此查询完美无缺。但只能使用UNION关键字。如何使用相关子查询获得相同的结果? (不能使用JOIN关键字)
我尝试使用这样的查询:
SELECT DISTINCT c.name AS "class_name" , st.name AS "staff_name", d.name AS "department_name"
FROM class c, staff st, department d
WHERE (c.staffid = st.staffid AND st.deptid = d.deptid AND d.deptid IS NOT NULL) OR NOT EXISTS (SELECT DISTINCT NULL AS "department_name" FROM staff staff, class class, department d WHERE staff.deptid IS NOT NULL AND staff.staffid = class.staffid);
但是这些查询并没有向我显示值为null的任何部门,只显示包含名称的部门。
如何使用不带JOIN / UNION关键字的子查询来表达这一点?
编辑:伙计们,我知道可能有更好的方法来解决这个问题。正如我在开始时说的,这是一次大学练习,我们的教授希望我们解决这个问题。我们很快就会了解JOIN。
答案 0 :(得分:0)
在SELECT
SELECT c.name AS "class_name" ,
st.name AS "staff_name",
(SELECT d.name FROM department d WHERE st.deptid = d.deptid) AS "department_name"
FROM class c, staff st
WHERE c.staffid = st.staffid
select后面的子查询必须始终返回一个值(因为员工属于一个部门)。如果工作人员不属于任何人员,则返回NULL
并且结果中没有消除工作人员(与内部联接相比)。
即使没有旧的连接语法也可以解决它,但是,这是非常模糊的解决方案:)
SELECT c.name AS "class_name" ,
(SELECT st.name FROM staff st WHERE c.staffid = st.staffid) AS "staff_name",
(SELECT
(SELECT d.name FROM department d WHERE st.deptid = d.deptid)
FROM staff st WHERE c.staffid = st.staffid
) AS "department_name"
FROM class c
答案 1 :(得分:0)
学习使用正确的,明确的JOIN
语法。切勿在{{1}}子句中使用逗号。
然后,你可能马上就认识到你需要一个FROM
:
LEFT JOIN
我怀疑是否需要SELECT DISTINCT c.name AS class_name, st.name AS staff_name" d.name AS department_name
FROM class c LEFT JOIN
staff st
ON c.staffid = st.staffid LEFT JOIN
department d
ON st.deptid = d.deptid;
。但是我把它留下了,因为你比我更了解数据。