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

时间:2017-03-04 09:42:06

标签: mysql sql sql-server join self-join

我有一张桌子 原始数据就像

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

我想要所有RollNumber数据,它们应具有不同的状态1和3 我需要的数据如下:

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

2 个答案:

答案 0 :(得分:3)

您可以使用聚合来查找在子查询中同时具有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。

答案 1 :(得分:0)

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