sql 组具有不超过 2 个不同的特定值

sql group has no more than 2 distinct specific values

我有一个table 原始数据就像

RollNumber | Subject | G         | Part | Status  
------------------------------------------------  
1          | 1       | 1         | 1    |  1  
1          | 1       | 1         | 2    |  1  
1          | 2       | 1         | 1    |  1  
1          | 2       | 1         | 2    |  5  
1          | 3       | 1         | 1    |  1  
1          | 3       | 1         | 2    |  1  
2          | 1       | 2         | 1    |  1  
2          | 1       | 2         | 2    |  1  
2          | 2       | 2         | 1    |  1  
2          | 2       | 2         | 2    |  1  
2          | 3       | 2         | 1    |  1  
2          | 3       | 2         | 2    |  1 
3          | 1       | 2         | 1    |  1  
3          | 1       | 2         | 2    |  1  
3          | 2       | 2         | 1    |  1  
3          | 2       | 2         | 2    |  1  
3          | 3       | 2         | 1    |  0  
3          | 3       | 2         | 2    |  1
4          | 1       | 2         | 1    |  1  
4          | 1       | 2         | 2    |  1  
4          | 2       | 2         | 1    |  1  
4          | 2       | 2         | 2    |  1  
4          | 3       | 2         | 1    |  3  
4          | 3       | 2         | 2    |  1

我想要所有应该具有不同状态 1 和 3 的 RollNumber 数据 我需要的数据是这样的:

RollNumber | Subject | G         | Part | Status  
------------------------------------------------ 
4          | 1       | 2         | 1    |  1  
4          | 1       | 2         | 2    |  1  
4          | 2       | 2         | 1    |  1  
4          | 2       | 2         | 2    |  1  
4          | 3       | 2         | 1    |  3  
4          | 3       | 2         | 2    |  1

我需要一个适用于所有 sql 的查询,也适用于 mysql

您可以使用聚合来查找在子查询中同时具有 1、3 作为状态的 rollnumbers,并使用它来获取所有相关行。

使用IN:

select *
from t
where rollnumber in (
        select rollnumber
        from t
        where status in (1, 3)
        group by rollnumber
        having count(distinct status) = 2
        );

使用JOIN:

select t1.*
from t t1
join (
    select rollnumber
    from t
    where status in (1, 3)
    group by rollnumber
    having count(distinct status) = 2
    ) t2 on t1.rollnumber = t2.rollnumber;

子查询过滤器使用 where 子句仅保留状态为 1 或 3 的行。然后在对 rollNumber 进行分组时,我们检查不同的状态计数是否为 2,这意味着该 rollNumber 同时存在 1 和 3。

Use HAVING and GROUP BY clause to get rollnumber having status 1 and 3 and finally join to get result.

CREATE TABLE #table(RollNumber INT, Subject INT, G INT,Part INT, Status INT)
INSERT INTO #table(RollNumber , Subject , G ,Part , Status )
SELECT 1          , 1       , 1         , 1    ,  1  UNION ALL
SELECT 1          , 1       , 1         , 2    ,  1  UNION ALL
SELECT 1          , 2       , 1         , 1    ,  1  UNION ALL
SELECT 1          , 2       , 1         , 2    ,  5  UNION ALL
SELECT 1          , 3       , 1         , 1    ,  1  UNION ALL
SELECT 1          , 3       , 1         , 2    ,  1  UNION ALL
SELECT 2          , 1       , 2         , 1    ,  1  UNION ALL
SELECT 2          , 1       , 2         , 2    ,  1  UNION ALL
SELECT 2          , 2       , 2         , 1    ,  1  UNION ALL
SELECT 2          , 2       , 2         , 2    ,  1  UNION ALL
SELECT 2          , 3       , 2         , 1    ,  1  UNION ALL
SELECT 2          , 3       , 2         , 2    ,  1  UNION ALL
SELECT 3          , 1       , 2         , 1    ,  1  UNION ALL
SELECT 3          , 1       , 2         , 2    ,  1  UNION ALL
SELECT 3          , 2       , 2         , 1    ,  1  UNION ALL
SELECT 3          , 2       , 2         , 2    ,  1  UNION ALL
SELECT 3          , 3       , 2         , 1    ,  0  UNION ALL
SELECT 3          , 3       , 2         , 2    ,  1  UNION ALL
SELECT 4          , 1       , 2         , 1    ,  1  UNION ALL
SELECT 4          , 1       , 2         , 2    ,  1  UNION ALL
SELECT 4          , 2       , 2         , 1    ,  1  UNION ALL
SELECT 4          , 2       , 2         , 2    ,  1  UNION ALL
SELECT 4          , 3       , 2         , 1    ,  3  UNION ALL
SELECT 4          , 3       , 2         , 2    ,  1

SELECT *
FROM #table T
JOIN 
(
   SELECT RollNumber 
   FROM #table
   WHERE Status IN (1,3)
   GROUP BY RollNumber 
   HAVING COUNT (DISTINCT Status) = 2
 )A ON A.RollNumber = T.RollNumber