在SQL server 2008上找到所有一列属于相同值,同时另一列满足一个条件的记录。

0 人关注

我需要在SQL server 2008上找到所有有一列属于相同值的记录,同时满足一个条件。

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

我需要得到所有col2=0的行,这些行与col1相同。

在这里,我希望

           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 ? 
    
2 个评论
你是说你不需要col1的值是100?
我假设你的起始集(或结果集)最后一行的 col1 (即 200 s/ 300 s的数量不匹配)有一个错字。
sql
sql-server
sql-server-2008
user3448011
user3448011
发布于 2014-05-24
4 个回答
Andriy M
Andriy M
发布于 2014-05-26
已采纳
0 人赞同

由于你需要一组 的结果,你可以使用分组,例如像这样。

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

这将给你所有[不同的]col1 值,其col2 总数为0。当然,这假设SUM 适用于这种情况--特别是col2 不是bitcol2 不能有负值。如果你真的想检查0作为行的特定值(或没有),你可以使用一个不同的聚合函数。

SELECT col1
FROM table1
GROUP BY col1
HAVING COUNT(NULLIF(col2, 0)) = 0

col2 上面的查询将计算每组col1 中的非0值,只返回那些计数为0的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

然而,还有另一种可能更有效的方法,在窗口聚合的帮助下做同样的事情,像这样。

SELECT
  col1,
  col2,
FROM (
  SELECT *, cnt = COUNT(NULLIF(col2, 0)) OVER (PARTITION BY col1)
  FROM table1
) AS s
WHERE cnt = 0

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

Praveena
Praveena
发布于 2014-05-26
0 人赞同

以下是询问内容。

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

希望这能对你有所帮助!

当然,如果有一组 col1 值都有相同的匹配的非 0 值,这也会返回这些值。 你可以增加一个什么条件来解决这个问题?
Serpiton
Serpiton
发布于 2014-05-26
0 人赞同

从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)
    
OP没有列出 col2 的所有可能的值,所以我犹豫是否要寻找一个具体的值来敲定,而宁愿使用我所知道的值......
Jithin Shaji
Jithin Shaji
发布于 2014-05-26
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
ON      A.col1 = LU.col1
WHERE   A.col2 = 0