SQL查询以获取外键中某个状态的所有记录

时间:2016-11-07 23:55:14

标签: mysql sql sql-server

我有一个相当大的表(10,000多条记录)看起来或多或少像这样:

| id | name  | contract_no | status |
|----|-------|-------------|--------|
| 1  | name1 | 1022        | A      |
| 2  | name2 | 1856        | B      |
| 3  | name3 | 1322        | C      |
| 4  | name4 | 1322        | C      |
| 5  | name5 | 1322        | D      |

contract_no是一个外键,当然可以出现在几个记录中,每个记录的状态为A,B,C,D或E.

我想要的是获取所有合同号的列表,其中引用该合同的所有记录都处于状态C,D,E或其中的混合,但是如果任何记录处于状态A或B,省略合同号。

是否可以使用SQL查询执行此操作?或者我应该更好地导出数据并尝试使用其他语言(如Python或R?

)运行此分析

3 个答案:

答案 0 :(得分:1)

您可以group byhaving一起使用来获取此类合同号。

select contract_number
from yourtable 
group by contract_number
having count(distinct case when status in ('C','D','E') then status end) >= 1
and count(case when status = 'A' then 1 end) = 0
and count(case when status = 'B' then 1 end) = 0

答案 1 :(得分:1)

发布聚合过滤应该可以解决问题

SELECT contract_no FROM t
GROUP BY contract_no
HAVING SUM(status='A')=0
AND SUM(status='B')=0

答案 2 :(得分:1)

不像其他两个答案那样优雅,但更具表现力:

SELECT DISTINCT contract_no
FROM the_table t1
WHERE NOT EXISTS (
    SELECT *
    FROM the_table t2
    WHERE t2.contract_no = t1.contract_no
    AND t2.status IN ('A', 'B')
)

SELECT DISTINCT contract_no
FROM the_table
WHERE contract_no NOT IN (
    SELECT contract_no
    FROM the_table
    AND status IN ('A', 'B')
)