我需要运行培训查询,返回以下问题的结果:“谁完成了此培训,但没有完成培训?”
在下面的简化表中,我想知道哪个员工已完成training_id 1(由completed_date字段中的日期表示),但尚未完成training_id 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中表达类似内容?
答案 0 :(得分:1)
您可以使用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
答案 1 :(得分:0)
select * from training where emp_id in
(
select distinct emp_id from training where completed_Date is not null
)
答案 2 :(得分:0)
您可以在此表上进行自联接(“假装它是两个相同的表并加入它们”):
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不。