【问题标题】:Group By with multiple condition CASE WHEN in Sql Server在 SQL Server 中使用多个条件 CASE WHEN 进行分组
【发布时间】:2023-01-09 07:26:06
【问题描述】:

我有一个名为 DMIntegration 的表,其中包含许多 dealerId:

DealerId  |  KPI   |  Value
----------------------------
  001          1        Y
  001          2        Y
  001          3        Y
  001          4        Y
  002          1        Y
  002          2        Y
  002          3        N
  002          4        Y

我想获得的是按 DealerId 分组,如果所有 KPI 值都为 Y,则为 1,否则为 0。如何根据多行指定 1 或 0?在这种情况下,它将是:

DealerId  |  Result
--------------------
   001         1     
   002         0

这就是我的想法,但我不知道如何为所有 KPI 设置一个值:

SELECT 
    DealerId
    ,CASE WHEN 
                (Value='Y' and KPI=1)    AND
                (Value='Y' and KPI=2)    AND
                (Value='Y' and KPI=3)    AND
                (Value='Y' and KPI=4)    AND        
    THEN 1
    ELSE 0
    END AS Result
FROM DMIntegration
group by DealerId

编辑: 在这种情况下,我决定按照你们中的一些人的建议这样做:

Select DealerId
      ,Result   = min(case when Value = 'Y' then 1 else 0 end)
 From  DMIntegration
 Group By DealerID 

但是,如果 KPI 在 (1,2) 中,Value ='Y' AND (KPI=3 OR KPI=4)(至少两者之一),Value ='Y',那么如果我想将 Result=1 放入呢? ?

编辑 2: 抱歉,我试图简化数据集,以便更容易理解。因此,我有 n 个 DealerId,其中每个 KPI 总共有 14 个 KPI,而 Value 字段对于 14 个 KPI 中的每一个都可以是 Y(是)或 N(否)。我想要做的是有一个表,其中我有经销商 ID 和一个包含布尔值的结果字段,具体取决于 KPI 和值字段。如果 KPI 1、2、3、4、6、7、8、10、11、12、13、14 均为“Y”且其余 KPI(5 和 9)中至少有一个等于“,则结果为 1是的。这是一个例子

DealerId  |  KPI   |  Value
----------------------------
  001          1        Y
  001          2        Y
  001          3        Y
  001          4        Y
  001          5        N
  001          6        Y
  001          7        Y
  001          8        Y
  001          9        N
  001         10       Y
  001         11       Y
  001         12       Y
  001         13       Y
  001         14       Y

在这种情况下,我有桌子

DealerId       Result
-----------------------------
001                 0

因为 5 和 9 是 N。如果只有 5 或 9 是 Y 那么 Result=1

【问题讨论】:

  • 您的 CASE 表达式没有意义,因为它只会处理一次排。不行可以满足所有这些条件。请创建一个示例数据集,然后创建您期望从该示例中获得的结果。
  • 编辑 2 的示例
  • DealerId, KPI 的组合是唯一的吗?或者 Dealer 是否可以针对同一个 KPI 获得多个结果?如果是这样,如果经销商有 12 个 Y 对应一个 KPI,或者一个 Y 和一个 N 对应同一个 KPI,应该如何处理?

标签: sql sql-server group-by case


【解决方案1】:

试试这个解决方案:

SELECT
  DealerId,
  CASE
    WHEN
      COUNT(
        DISTINCT
        CASE
          WHEN [value] = 'Y'
           AND [kpi]  IN (1, 2, 3, 4, 6, 7, 8, 10, 11, 12, 13, 14)
          THEN [kpi]
        END
      )
      = 12
    AND
      COUNT(
        DISTINCT
        CASE
          WHEN [value] = 'Y'
           AND [kpi]  IN (5, 9)
          THEN [kpi]
        END
      )
      > 0
    THEN
      1
    ELSE
      0
  END
    AS Result
FROM
  DMIntegration
GROUP BY
  DealerId

https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=fb993eabdd7a17ff9d4e3cb138b04cb6


或者,一个轻微地更通用的版本...

  • 每个KPI都匹配一个group
  • 每个group必须至少有1个KPI,其中valueY
  • 所以,(1, 2, 3, 4, 6, 7, 8, 10, 11, 12, 13, 14)都在他们自己的组里(他们都需要是Y
  • (5, 9)都在第5组(其中一个需要是Y

创建条件映射...

WITH
  filter
AS
(
  SELECT
    *
  FROM
  (
    VALUES
      ( 1, 'Y',  1),
      ( 2, 'Y',  2),
      ( 3, 'Y',  3),
      ( 4, 'Y',  4),
      ( 5, 'Y',  5),  -- This and 9 have the same filter_group_id, only one needs be true
      ( 6, 'Y',  6),
      ( 7, 'Y',  7),
      ( 8, 'Y',  8),
      ( 9, 'Y',  5),  -- This and 5 have the same filter_group_id, only one needs be true
      (10, 'Y', 10),
      (11, 'Y', 11),
      (12, 'Y', 12),
      (13, 'Y', 13),
      (14, 'Y', 14)
  )
    AS filter(kpi, value, group_id)
)

那么加入和计数不同......

SELECT
  d.DealerId,
  CASE WHEN
    COUNT(DISTINCT f.group_id)
    =
    (SELECT COUNT(DISTINCT group_id) FROM filter)
  THEN
    1
  ELSE
    0
  END
    AS Result
FROM
  DMIntegration   AS d
LEFT JOIN
  filter          AS f
    ON  f.kpi   = d.kpi
    AND f.value = d.value
GROUP BY
  d.DealerId

https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=e4bdf712bc098385b75d16a6c0717186

【讨论】:

    【解决方案2】:

    或者也...

    WITH
    -- your input ..                                                                                                                                                                                               
    indata(DealerId,KPI,Value) AS (
              SELECT '001',1,'Y'
    UNION ALL SELECT '001',2,'Y'
    UNION ALL SELECT '001',3,'Y'
    UNION ALL SELECT '001',4,'Y'
    UNION ALL SELECT '002',1,'Y'
    UNION ALL SELECT '002',2,'Y'
    UNION ALL SELECT '002',3,'N'
    UNION ALL SELECT '002',4,'Y'
    )
    SELECT
      dealerId
    , CASE COUNT(*)
        WHEN SUM(CASE value WHEN 'Y' THEN 1 ELSE 0 END) THEN 1
        ELSE 0
      END AS result
    FROM indata
    GROUP BY dealerid;
    -- out  dealerId | result 
    -- out ----------+--------
    -- out  001      |      1
    -- out  002      |      0
    

    【讨论】:

      猜你喜欢
      • 2013-01-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-04
      • 2021-08-04
      • 2012-05-11
      • 2017-04-20
      相关资源
      最近更新 更多