我有一张关于员工及其经理的简单表格。我想显示两列,一列具有雇员姓名,另一列具有雇员的经理姓名,如果雇员没有经理,则表应返回null。
我可以使用SELF JOIN来提取经理姓名,但是很难将其用作列。
这是表结构:
CREATE TABLE employees (
id INTEGER NOT NULL PRIMARY KEY,
mgrId INTEGER REFERENCES employees(id),
name VARCHAR(30) NOT NULL
);
INSERT INTO employees(id, mgrId, name) VALUES(1, NULL, 'Joey');
INSERT INTO employees(id, mgrId, name) VALUES(2, 1, 'Ross');
INSERT INTO employees(id, mgrId, name) VALUES(3, 1, 'Chandler');
INSERT INTO employees(id, mgrId, name) VALUES(4, 2, 'Monica');
这是我的解决方案,但输出显示JoeY为所有人的经理:
SELECT name, (SELECT e1.name
FROM employees as e1 JOIN employees as e2
ON e1.id = e2.mgrId) AS manager
FROM employees
这是我要打印的内容(Joey没有管理员,因此为null):
NAME Manager
---------- -------
Joey
Ross Joey
Chandler Joey
Monica Ross
答案 0 :(得分:2)
您需要外部联接才能产生所需的结果:
select
e.name,
m.name as manager
from employees e
left join employees m on m.id = e.mgrid
order by e.name
请参见DB Fiddle上的运行示例。
答案 1 :(得分:1)
您的子查询与您的主查询没有关联,这就是为什么它为每个人返回相同结果的原因。将其更改为关联的子查询将解决您的问题:
SELECT e2.name, (SELECT name FROM employees as e1 WHERE e1.id = e2.mgrId) AS manager
FROM employees e2
输出:
name manager
Joey null
Ross Joey
Chandler Joey
Monica Ross
答案 2 :(得分:1)
您刚刚在内部查询中做了一个额外的联接,该联接应该是:
SELECT name, (SELECT e1.name
FROM employees as e1
WHERE e1.id = e2.mgrId) AS manager
FROM employees e2
答案 3 :(得分:0)
我是否可以建议对数据进行不同的建模(请查看Vanilla Peoplesoft HR数据模型以获取灵感),但为简单起见,我仅添加了一个位置表,以下查询提供了具有更大灵活性的预期结果:< / p>
Select e.id, e.positionid, e.name, p.positionid_reports_to, m.name as Manager
FROM employee e
Left Join position p on e.positionid = p.positionid
Left Join employee m on p.positionid_reports_to = m.positionid;
基于以下数据:
INSERT INTO employee(id, positionId, name) VALUES(1, 101, 'Boss');
INSERT INTO employee(id, positionId, name) VALUES(2, 102, 'Joey');
INSERT INTO employee(id, positionId, name) VALUES(3, 103, 'Ross');
INSERT INTO employee(id, positionId, name) VALUES(4, 104, 'Chandler');
INSERT INTO employee(id, positionId, name) VALUES(5, 105, 'Monica');
INSERT INTO position(positionid, positionid_reports_to) VALUES(101, null);
INSERT INTO position(positionid, positionid_reports_to) VALUES(102, 101);
INSERT INTO position(positionid, positionid_reports_to) VALUES(103, 101);
INSERT INTO position(positionid, positionid_reports_to) VALUES(104, 101);
INSERT INTO position(positionid, positionid_reports_to) VALUES(105, 101);