【问题标题】:SQL Check if ungroup column values matchSQL 检查取消分组列值是否匹配
【发布时间】:2013-01-14 08:29:28
【问题描述】:

我有一个包含以下值的 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 的分组获得带有标志的输出:

  • 所有值都匹配一个组(标志 = 1)
  • 所有值都为空(标志 = 2)
  • 某些值为空(标志 = 3)

输出:

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

【问题讨论】:

  • 你使用的是什么 rdbms?
  • 应该如何评估这个flag 列?

标签: sql sql-server group-by aggregate


【解决方案1】:

或者:根据您更新的问题:

  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 |

注意:我假设标志是VALUES 列中有多少NULL 值,所以我使用"Values" IS NULL 而不是SomeConditionHere

我不明白应该如何在您发布的预期结果中计算 flag。您必须使用定义标志的谓词而不是 "Values" IS NULL

更新:

试试这个:

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;

Updated SQL Fiddle Demo

这会给你:

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

【讨论】:

  • 感谢您。通过标志,我的意思是如果所有值都匹配一个组(标志 = 1),如果所有值都为空(标志 = 2),如果任何值为空(标志 = 3)再次感谢
  • @mushtaqck 好的,对不起,我错过了。所以这是针对values 列中的值,而不是score 列?对吗?
【解决方案2】:

在 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上的演示

【讨论】:

    【解决方案3】:

    ...如果您想要更便携的解决方案,则无需 CTE SQL

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-07
      • 1970-01-01
      • 2019-11-26
      相关资源
      最近更新 更多