Условный запрос для анализа обучения сотрудников - PullRequest
3 голосов
/ 02 марта 2011

Мне нужно выполнить запросы на обучение, которые возвращают результаты для таких вопросов, как: «Кто прошел это обучение, но не этот тренинг?»

В приведенной ниже упрощенной таблице я хотел бы знать, какой сотрудник прошел тренинг_ид 1 (как указано в поле даты_даты), но не завершил тренинг_ид 7.

+-------------+-------------+----------------+
| emp_id      | training_id | completed_date |
+-------------+-------------+----------------+
| 1           | 1           | 2010-04-02     |
+-------------+-------------+----------------+
| 1           | 7           | Null           |
+-------------+-------------+----------------+
| 2           | 1           | Null           |
+-------------+-------------+----------------+
| 2           | 7           | Null           |
+-------------+-------------+----------------+

Желаемый результат будет emp_id 1, и мы хотели бы вернуть его / ее завершенное обучение и незавершенное обучение по параметрам запроса:

+-------------+-------------+----------------+
| emp_id      | training_id | completed_date |
+-------------+-------------+----------------+
| 1           | 1           | 2010-04-02     |
+-------------+-------------+----------------+
| 1           | 7           | Null           |
+-------------+-------------+----------------+

Я не могу понять, как это сделать с помощью обычного запроса, потому что, похоже, ему нужна логика IF. Пример: вернуть строки, в которых эта тренировка завершена, и строки, в которых эта вторая тренировка не завершена, НО ТОЛЬКО, если первая тренировка завершена.

Как мне выразить что-то подобное в SQL?

Ответы [ 3 ]

1 голос
/ 02 марта 2011

Вы можете использовать предложение EXISTS

SELECT t.*
FROM training t

# which employee has completed training_id 1
WHERE t.training_id = 1 and t.completed_date is not null

#but has not finished training_id 7.
AND NOT EXISTS (
     SELECT * FROM training t2
     where t2.emp_id=t.emp_id
       and t2.training_id = 7
       and t2.completed_date is not null)

Если вы хотите протестировать что-то более сложное, например completed (4,5,6) but not (1,9), тогда вы можете использовать счетчики:

SELECT t.emp_id
FROM training t
WHERE t.training_id in (4,5,6) and t.completed_date is not null
group by t.emp_id
having count(distinct emp_id) = 3

AND NOT EXISTS (
     SELECT * FROM training t2
     where t2.emp_id=t.emp_id
       and t2.training_id in (1,9)
       and t2.completed_date is not null)

И, наконец, есливам нужна полная запись об обучении сотрудников

SELECT e.*
FROM
(
    SELECT t.emp_id
    FROM training t
    WHERE t.training_id in (4,5,6) and t.completed_date is not null
    group by t.emp_id
    having count(distinct emp_id) = 3

    AND NOT EXISTS (
         SELECT * FROM training t2
         where t2.emp_id=t.emp_id
           and t2.training_id in (1,9)
           and t2.completed_date is not null)
) search
inner join training e on e.emp_id = search.emp_id
order by e.emp_id
0 голосов
/ 02 марта 2011

Вы можете выполнить самостоятельное объединение для этой таблицы («представьте, что это две идентичные таблицы и соедините их»):

SELECT t1.emp_id, t1.training_id, t1.completed_date,
       t2.training_id, t2.completed_date
    FROM training AS t1 /* the aliases are needed for the self-join */
    JOIN training AS t2
        ON t1.emp_id = t2.emp_id
        AND t2.training_id = 7 /* second training  ID */
    WHERE t1.training_id = 1 /* first training ID */

Это должно дать вам такой результат:

t1.emp_id | t1.training_id | t1.completed_date | t2.training_id | t2.completed_date
 1            1               2010-04-02          7                NULL
 2            1               NULL                7                NULL

Затем вы можете дополнительно ограничить запрос WHERE, например, с помощью

         AND t1.completed_date IS NOT NULL
         AND t2.completed_date IS NULL

, который даст вам желаемый набор - тренинг 1 завершен, тренинг 7 - нет.

0 голосов
/ 02 марта 2011
select * from training where emp_id in
(
  select distinct emp_id from training where completed_Date is not null
)
...