首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >MYSQL:SQL查询,只有当所有行都满足条件时才返回行

MYSQL:SQL查询,只有当所有行都满足条件时才返回行
EN

Stack Overflow用户
提问于 2013-09-26 05:51:25
回答 3查看 9.8K关注 0票数 7

考虑三张表-

代码语言:javascript
运行
复制
  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)。它是一个用户还没有接受培训,将不会有任何行的培训。

我想找出所有的用户谁已经成功地完成了所有的培训,他们必须参加。

以下是我正在思考的方向:

代码语言:javascript
运行
复制
select
  id
from users
  join types
    using (type)
  left join training_status
    using (id,type)
where status NOT IN(None, F);

显然,这不是正确的查询,因为即使用户完成了一次培训,我们也会得到该行。在前面的例子中,我想得到id =2,因为他已经完成了这两个类型的培训。

EN

回答 3

Stack Overflow用户

发布于 2013-09-26 06:11:11

尝尝这个

代码语言:javascript
运行
复制
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')
票数 0
EN

Stack Overflow用户

发布于 2013-09-26 06:12:57

尝尝这个

代码语言:javascript
运行
复制
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'
票数 0
EN

Stack Overflow用户

发布于 2013-09-26 06:44:12

这应该是可行的:

代码语言:javascript
运行
复制
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版本:

代码语言:javascript
运行
复制
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)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19020334

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档