Sql Server中具有多个条件的Group By CASE WHEN

3hvapo4f  于 2023-01-12  发布在  SQL Server
关注(0)|答案(2)|浏览(175)

我有一个名为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

但如果我想把结果= 1,如果KPI在(1,2)与值='Y '和(KPI = 3或KPI = 4)(至少两者之一)?
编辑2:抱歉,我试图简化数据集,使其更易于理解。因此,我有n个DealerId,每个DealerId总共有14个KPI,值字段可以为Y(是)或否(否)。我想要做的是创建一个表,其中包含经销商ID和一个"结果"字段,该字段包含取决于KPI和"值"字段的布尔值。如果KPI 1、2、3、4、6、7、8、10、11、12、13、14均为"Y",并且其余KPI(5和9)中至少有一个等于"Y"。下面是一个示例

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,则结果= 1

f0brbegy

f0brbegy1#

尝试此解决方案:

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,其中value等于Y
  • 因此,(1, 2, 3, 4, 6, 7, 8, 10, 11, 12, 13, 14)都在自己的组中(它们都需要是Y
  • (5, 9)都在组5中(其中一个需要是Y

创建条件Map...

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

e0uiprwp

e0uiprwp2#

或者...

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

相关问题