SQL检查取消组合列值是否匹配

时间:2013-01-14 08:29:28

标签: sql sql-server group-by aggregate

我有一个包含以下值的SQL表

       |  col1 | col2|   source |  values
       |  1    |  2  |  A       |   null
       |  1    |  2  |  B       |   1.0
       |  1    |  2  |  C       |   null
       |  1    |  4  |  A       |   2.0
       |  1    |  4  |  B       |   2.0
       |  1    |  4  |  C       |   2.0
       |  1    |  5  |  A       |   null
       |  1    |  5  |  B       |   null
       |  1    |  5  |  C       |   null

如何使用带有标记的col1col2组获得输出:

  • 所有值都匹配组(flag = 1)
  • 所有值均为null(flag = 2)
  • 某些值为null(flag = 3)

输出:

       |  col1 | col2|   flag
       |  1    |  2  |   3
       |  1    |  4  |   1
       |  1    |  5  |   2

3 个答案:

答案 0 :(得分:3)

根据您更新的问题

或<:strong>:

  SELECT 
    col1, 
    col2,
    SUM(CASE WHEN SomeConditionHere THEN 1 ELSE 0 END) AS Flag
  FROM Table1
  GROUP BY col1, col2;

SQL Fiddle Demo

这会给你:

| COL1 | COL2 | FLAG |
----------------------
|    1 |    2 |    2 |
|    1 |    4 |    0 |
|    1 |    5 |    3 |

请注意:我认为该标志是NULL列中有多少VALUES个值,因此我使用"Values" IS NULL代替{{1} }}。

我无法理解如何在您发布的预期结果中计算SomeConditionHere。您必须使用定义标志的谓词而不是flag

<击>

更新

试试这个:

"Values" IS NULL

Updated SQL Fiddle Demo

这会给你:

WITH Flags
AS
(
  SELECT 
    col1, col2,
    COUNT(*) ValuesCount,
    SUM(CASE WHEN "Values" IS NULL THEN 1 ELSE 0 END) AS NULLValues
  FROM Table1 
  GROUP BY col1, col2
)
SELECT 
  col1,
  col2,
  Flag = CASE WHEN ValuesCount = NULLValues THEN 2
              WHEN NULLVALUES = 0 
               AND ValuesCount = (SELECT COUNT(*) 
                                  FROM Table1 t2
                                  WHERE t1.col1 = t2.col1
                                    AND t1.col2 = t2.col2) THEN 1
               ELSE 3
END
FROM Flags t1;

答案 1 :(得分:3)

在SQLServer2005 +

;WITH cte AS
 (
  SELECT col1, col2, [values],       
         COUNT(CASE WHEN [values] IS NULL THEN 1 END) OVER(PARTITION BY col1, col2) AS cntNULL,
         COUNT(*) OVER(PARTITION BY col1, col2) AS cntCol
  FROM dbo.test5
  )
  SELECT col1, col2, MAX(CASE WHEN cntNULL = 0 THEN 1
                              WHEN cntNULL = cntCol THEN 2
                              ELSE 3 END) AS flag
  FROM cte
  GROUP BY col1, col2  

SQLFiddle上的演示

答案 2 :(得分:2)

...如果你想要更便携的SQL,那么没有CTE的解决方案:

select col1,
       col2,
        case 
            when DistinctValuesWithoutNulls = 1 and NullCount = 0 then 1 
            when DistinctValuesWithoutNulls = 0 then 2
            when NullCount > 0 then 3
        end flag
from
(
    select  col1, 
            col2, 
            count(distinct [values]) DistinctValuesWithoutNulls, 
            sum(case when [values] is null then 1 else 0 end) NullCount
    from Table1
    group by col1, col2
) tmp