查找一列属于同一值的所有行,另一列满足SQL Server 2008上的条件

时间:2014-05-24 15:42:09

标签: sql sql-server sql-server-2008

我需要找到一列属于同一个值的所有行,并且还满足SQL Server 2008上的条件。

表1:

       col1    col2 
       100     0
       100     1
       100     1
       200     0
       200     0
       200     0
       300     0
       300     0
       200     0

我需要为同一个col1获取所有col2 = 0的行。

在这里,我希望

           col1    col2 
           200     0
           200     0
           200     0
           300     0
           300     0
           300     0

因为 col1 = 200且col1 = 300 所有col2为0

   SELECT *
   FROM table1 as a
   where a.col2  = 0    # but, how to say col1 belong to the same value ? 

THX!

4 个答案:

答案 0 :(得分:2)

由于您需要行组的结果,因此您可以使用分组,例如像这样:

SELECT col1
FROM table1
GROUP BY col1
HAVING SUM(col2) = 0
;

这会为您提供col1总计为0的所有[不同] col2值。当然,假设SUM适用于这种情况 - 特别是{ {1}}不是col2,而bit不能包含负值。如果你真的想要检查0作为具有(或没有)行的特定值,你可以使用不同的聚合函数:

col2

上述查询会计算SELECT col1 FROM table1 GROUP BY col1 HAVING COUNT(NULLIF(col2, 0)) = 0 ;每组col2的非0值,并仅返回计数为0的col1值。

最后,如果您确实需要返回详细信息行而不是不同的col1值,则可以将上述查询的结果用作派生表并过滤其上的源表:

col1

然而,在窗口聚合的帮助下,还有另一种可能更有效的方法,如下所示:

SELECT *
FROM table1
INNER JOIN (
  SELECT col1
  FROM table1
  GROUP BY col1
  HAVING COUNT(NULLIF(col2, 0)) = 0
) AS filter
ON table1.col1 = filter.col1
;

上述查询中的计数将与详细数据一起返回,外部查询只会对它们进行过滤,最终只生成计数为0的行。不同的是,这方法仅引用源表一次,这可能导致比以前的方法更有效的查询计划。

答案 1 :(得分:1)

从SQLServer 2005,我们可以使用EXCEPT关键字,这与UNION相反,例如它从第一个查询的结果集中删除第二个查询的行,在本例中为

SELECT col1, col2
FROM   table1 a
WHERE  a.col2  = 0 
EXCEPT
SELECT col1, 0
FROM   table1 as a
WHERE  a.col2  <> 0

EXCEPT仅返回不同的行,因此NOT EXISTS版本可能会更好

SELECT *
FROM   table1 t1
WHERE  NOT EXISTS (SELECT 1
                   FROM   table1 t2
                   WHERE  t1.col1 = t2.col1
                     AND  t2.col2 <> 0)

答案 2 :(得分:1)

以下是查询:

select col1,col2 from samp a
where not exists (select 1 from samp
                            where col1 = a.col1
                and col2 <> a.col2)

希望这会对你有帮助!

答案 3 :(得分:0)

我不确定,我是否理解你的问题。 请参阅解决方案。

DECLARE @TABLE TABLE (col1 int,col2 int)
INSERT INTO @TABLE VALUES 
(100,0),
(100,1),
(100,1),
(200,0),
(200,0),
(200,0),
(300,0),
(300,0),
(200,0)

SELECT  A.*
FROM    @TABLE A    
JOIN    (   
        SELECT col1 FROM @table WHERE col2 = 0
        GROUP BY col1 HAVING COUNT(*) > 1
        ) lU 
ON      A.col1 = LU.col1
WHERE   A.col2 = 0

enter image description here

编辑:已修改SQL。

SELECT  * FROM @table
WHERE   col1 IN
        (
        SELECT  A.col1
        FROM    (
                SELECT      col1,COUNT(*) [Count]
                FROM        @table 
                GROUP BY    col1 
                HAVING      COUNT(*) > 1) A
        JOIN    (
                SELECT      col1,COUNT(*) [Count]
                FROM        @table WHERE col2 = 0
                GROUP BY    col1 
                HAVING      COUNT(*) > 1) B
        ON      A.col1 = B.col1
        AND     A.Count = B.Count
        )

enter image description here