SQL-запрос для сопоставления нескольких значений в одном столбце
У меня есть таблица в MySQL следующим образом.
Id Designation Years Employee
1 Soft.Egr 2000-2005 A
2 Soft.Egr 2000-2005 B
3 Soft.Egr 2000-2005 C
4 Sr.Soft.Egr 2005-2010 A
5 Sr.Soft.Egr 2005-2010 B
6 Pro.Mgr 2010-2012 A
Мне нужно получить Работников, которые работали как Soft.Egr и Sr.Soft.Egr и Pro.Mgr. В запросе невозможно использовать IN или несколько AND. Как это сделать?
Ответы
Ответ 1
То, что вы действительно можете найти, это реляционное разделение, даже если ваши физические требования запрещают использование AND
(по какой-либо причине?). Это сложно, но можно правильно выразить в SQL.
Реляционное разделение в прозе означает: найдите тех сотрудников, у которых есть запись в таблице сотрудников для всех существующих обозначений. Или в SQL:
SELECT DISTINCT E1.Employee FROM Employees E1
WHERE NOT EXISTS (
SELECT 1 FROM Employees E2
WHERE NOT EXISTS (
SELECT 1 FROM Employees E3
WHERE E3.Employee = E1.Employee
AND E3.Designation = E2.Designation
)
)
Чтобы увидеть приведенный выше запрос в действии, рассмотрите SQLFiddle
Хороший ресурс, объясняющий реляционное деление, можно найти здесь:
http://www.simple-talk.com/sql/t-sql-programming/divided-we-stand-the-sql-of-relational-division
Ответ 2
Один из способов:
select Employee
from job_history
where Designation in ('Soft.Egr','Sr.Soft.Egr','Pro.Mgr')
group by Employee
having count(distinct Designation) = 3
Ответ 3
Если вам нужно получить дополнительную информацию о каждой из ролей (например, даты), то соединение с исходной таблицей для каждого из дополнительных обозначений является возможным решением:
SELECT t.Employee, t.Designation, t.Years, t1.Designation, t1.Years, t2.Designation, t2.Years
FROM Table t
INNER JOIN t2 ON (t2.Employee = t.Employee AND t2.Designation = 'Sr.Soft.Egr')
INNER JOIN t3 ON (t3.Employee = t.Employee AND t3.Designation = 'Soft.Egr')
WHERE t.Designation = 'Pro.Mgr';
Ответ 4
Почему бы не следующее (для postgresql)?
SELECT employee FROM Employees WHERE Designation ='Sr.Soft.Egr'
INTERSECT
SELECT employee FROM Employees WHERE Designation ='Soft.Egr'
INTERSECT
SELECT employee FROM Employees WHERE Designation ='Pro.Mgr'
Ссылка на SQLfiddle
Я знаю, что это может не оптимизироваться, но я нахожу это намного легче понять и изменить.
Ответ 5
Попробуйте этот запрос:
SELECT DISTINCT t1.employee,
t1.designation
FROM tempEmployees t1, tempEmployees t2, tempEmployees t3
WHERE t1.employee = t2.employee AND
t2.employee = t3.employee AND
t3.employee = t1.employee AND
t1.designation != t2.designation AND
t2.designation != t3.designation AND
t3.designation != t1.designation