Подтвердить что ты не робот

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. Как это сделать?

4b9b3361

Ответ 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