SQL查询:如何跨行和列进行选择

时间:2016-10-11 18:11:12

标签: html sql sql-server-2008

我确定这是一个简单的WHERE子句。我只是不确定如何写它。

让我说我有以下数据,其中a,b,c(数字)和d(varchar):

enter image description here

我要做的是选择具有以下条件的行:

  • 列b必须与至少另一行相同。
  • 列c必须 至少有一行有一个值而一个没有或一个有0作为a 值。

我想拉上col a和d。但只有当b和c符合这些条件时才会这样。

例如绿色数据是我想要选择的,而红色显然是我不关心的数据。提前谢谢。

3 个答案:

答案 0 :(得分:1)

如果您只想要b值,请使用聚合和having

select b
from t
group by b
having count(*) > 1 and
       max(c) > 0 and
       min(coalesce(c, 0)) = 0;

这假设c始终为正。如果c可能是否定的,那么可以制定类似的逻辑。

如果您想要原始行,可以将这些结果重新加入表格,或使用in

答案 1 :(得分:1)

这应该这样做:

示例数据:

IF OBJECT_ID('tempdb..#TABLE') IS NOT NULL
DROP TABLE #TABLE

CREATE TABLE #TABLE (A int, B int , C int) 

INSERT INTO  #TABLE ( A, B  , C )  
VALUES
(0,1,0),
(1,1,253),
(2,4,800),
(3,5,460),
(4,6,300),
(5,7,350),
(6,7,450)

QUERY:

;WITH CTE --<-- this is a common table expression, it is essentially the same as having temp tables but it is in memory. Just google CTE tSQL and you will find out more about it.
    AS (SELECT *
            , rn = ROW_NUMBER() OVER(PARTITION BY B ORDER BY A) --this assigns a row number to the rows that are partitioned by the values in B. 
        FROM   #TABLE)
    SELECT A
        , B
        , C
    FROM   CTE
    WHERE  B IN
             (SELECT B --<-- here filter to only return the rows that have an rn (row number) greater than 1 meaning there are more than one row for the given value in B
              FROM   CTE
              WHERE  rn > 1) AND B IN (SELECT B --<-- here we filter further to ensure at least 1 record has the value 0.
              FROM   CTE
              WHERE C = 0 AND B IN (SELECT B --<--this is to ensure that at least there is one value that is not 0 to handle the bug pointed out by Jay.
          FROM   CTE
          WHERE C <> 0));

结果:

enter image description here

有关CTE's

的更多信息

有关ROW_NUMBER()

的更多信息

答案 2 :(得分:1)

您也可以使用JOINS生成所需的结果:

SELECT [tab].*
FROM
(
    SELECT tab1.B
    FROM #TABLE tab1
    GROUP BY tab1.B
    HAVING COUNT(tab1.A) > 1
) Tab1
INNER JOIN
(
    SELECT tab2.B
    FROM #TABLE tab2
    WHERE tab2.C IS NOT NULL
          AND (tab2.C IS NULL
               OR tab2.C = 0)
    GROUP BY tab2.B
) Tab2 ON Tab1.B = Tab2.B
INNER JOIN #TABLE [tab] ON tab.B = Tab2.B;