Есть ли способ использовать оператор SELECT в качестве столбца? - PullRequest
0 голосов
/ 09 ноября 2019

У меня есть эта простая таблица на сотрудников и их руководителей. Я хочу показать две колонки: в одной есть имя сотрудника, а в другой - имя менеджера, если у сотрудника нет менеджера, таблица должна возвращать ноль.

Я могу использовать 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

Это то, что яхочу напечатать (у Джоуи нет менеджера, следовательно, ноль):

NAME        Manager
----------  -------
Joey
Ross        Joey
Chandler    Joey
Monica      Ross

Ответы [ 4 ]

2 голосов
/ 09 ноября 2019

Вам нужно внешнее объединение, чтобы получить желаемый результат:

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 голос
/ 09 ноября 2019

Вы только что сделали дополнительное объединение во внутреннем запросе, который должен был быть:

SELECT name, (SELECT e1.name
          FROM employees as e1
          WHERE e1.id = e2.mgrId) AS manager 
FROM employees e2
1 голос
/ 09 ноября 2019

Ваш подзапрос не имеет корреляции с вашим основным запросом, поэтому он возвращает одинаковый результат для всех. Изменение его на коррелированный подзапрос исправит вашу проблему:

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

Демонстрация на dbfiddle

0 голосов
/ 09 ноября 2019

Могу ли я предложить моделирование данных по-другому (для вдохновения ознакомьтесь с моделью данных HR ванильной компанииoplesoft), но для простоты я только что добавил в таблицу позиций, и следующий запрос дает ожидаемый результат с большей гибкостью:

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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...