考虑三张表-
users
id | type
-----------|------------
1 | a
2 | b
3 | c
types
id | type
-----------|------------
a | X
a | Y
b | X
c | X
c | Y
c | Z
training_status
id | training| status
-----------|-----------|-------------
1 | X | F
2 | X | S
2 | Y | S
3 | X | F
3 | Y | S每个用户都有一个类型,类型定义了每个特定类型的用户必须完成的培训。
training_status包含用户所接受的所有培训的状态及其结果(S,F)。它是一个用户还没有接受培训,将不会有任何行的培训。
我想找出所有的用户谁已经成功地完成了所有的培训,他们必须参加。
以下是我正在思考的方向:
select
id
from users
join types
using (type)
left join training_status
using (id,type)
where status NOT IN(None, F);显然,这不是正确的查询,因为即使用户完成了一次培训,我们也会得到该行。在前面的例子中,我想得到id =2,因为他已经完成了这两个类型的培训。
发布于 2013-09-26 06:11:11
尝尝这个
SELECT *
FROM users
WHERE id NOT IN (
SELECT u.id
FROM users u
JOIN types t
ON u.type = t.type
LEFT JOIN training_status s
ON u.id = s.id AND t.training = s.training
WHERE s.status IS NULL OR s.status = 'F')发布于 2013-09-26 06:12:57
尝尝这个
select distinct
u.id
from users u
left join types t
on u.type = t.type
left join training_status ts
on ts.training = t.training
where ts.status is not null
and ts.status != 'F'发布于 2013-09-26 06:44:12
这应该是可行的:
SELECT id
FROM users
WHERE id not in (SELECT x.id FROM (SELECT u.id AS id, t.type AS type, 'S' AS status
FROM users u, types t
WHERE u.type = t.id
EXCEPT
SELECT id, training, status
FROM training_status
) AS x (id, type, status)
)注意,它使用了set操作符,除非它给出了所有可能的用户的行的不同,以及它们成功的训练组合和当前的培训状态。如果所有用户的当前状态都已完成,则差异不应产生任何行。非零结果意味着有用户没有完成所需的培训。最外层的选择给出未完成培训的用户列表,即未完成培训的用户列表!
当您的数据在MS中执行时,它给出了答案2,谁是唯一成功完成培训的人。
以下是MySQL版本:
SELECT id
FROM users
WHERE id not in (SELECT x.id
FROM (SELECT u.id AS id, t.type AS type, 'S' AS status
FROM users u, types t
WHERE u.type = t.id
) x
WHERE NOT EXISTS
(SELECT ts.id, ts.training, ts.status
FROM training_status ts
WHERE ts.id = x.id AND
ts.training = x.type AND
ts.status = x.status
)
)
+------+
| id |
+------+
| 2 |
+------+
1 row in set (0.00 sec)https://stackoverflow.com/questions/19020334
复制相似问题