【问题标题】:Using EXISTS within a GROUP BY clause在 GROUP BY 子句中使用 EXISTS
【发布时间】:2019-10-03 10:54:23
【问题描述】:

是否可以执行以下操作:
我有一个看起来像这样的表:

declare @tran_TABLE TABLE(
EOMONTH DATE,
AccountNumber INT,
CLASSIFICATION_NAME VARCHAR(50),
Value Float

)

INSERT INTO @tran_TABLE VALUES('2018-11-30','123','cat1',10)
INSERT INTO @tran_TABLE VALUES('2018-11-30','123','cat1',15)
INSERT INTO @tran_TABLE VALUES('2018-11-30','123','cat1',5 )
INSERT INTO @tran_TABLE VALUES('2018-11-30','123','cat2',10)
INSERT INTO @tran_TABLE VALUES('2018-11-30','123','cat3',12)
INSERT INTO @tran_TABLE VALUES('2019-01-31','123','cat1',5 )
INSERT INTO @tran_TABLE VALUES('2019-01-31','123','cat2',10)
INSERT INTO @tran_TABLE VALUES('2019-01-31','123','cat2',15)
INSERT INTO @tran_TABLE VALUES('2019-01-31','123','cat3',5 )
INSERT INTO @tran_TABLE VALUES('2019-01-31','123','cat3',2 )
INSERT INTO @tran_TABLE VALUES('2019-03-31','123','cat1',15)


EOMONTH     AccountNumber   CLASSIFICATION_NAME     Value
2018-11-30  123                     cat1                10
2018-11-30  123                     cat1                15
2018-11-30  123                     cat1                5
2018-11-30  123                     cat2                10
2018-11-30  123                     cat3                12
2019-01-31  123                     cat1                5
2019-01-31  123                     cat2                10
2019-01-31  123                     cat2                15
2019-01-31  123                     cat3                5
2019-01-31  123                     cat3                2
2019-03-31  123                     cat1                15

我想生成一个结果,它将检查每个月的每个 AccountNumber(在这种情况下只有一个)是否存在 CLASSIFICATION_NAME cat1、cat2、cat3。
如果该月所有 3 个都存在,则返回 1,但如果缺少任何一个,则返回 0。

结果应该是这样的:

EOMONTH     AccountNumber   CLASSIFICATION_NAME
2018-11-30    123                   1                               
2019-01-31    123                   1                       
2019-03-31    123                   0   

但我希望尽可能紧凑地进行操作,而不是先创建一个按 CLASSIFICATION_NAME、EOMONTH 和 AccountNumber 对所有内容进行分组的表,然后从该表中进行选择。
例如,在下面的伪代码中,是否可以使用 EXISTS 语句进行分组?

SELECT 
    EOMONTH
    ,AccountNumber
    ,CASE WHEN EXISTS (CLASSIFICATION_NAME = 'cat1' AND 'cat2' AND 'cat3') THEN 1 ELSE 0 end 
    ,SUM(Value) AS totalSpend
FROM @tran_TABLE
GROUP BY 
    EOMONTH
    ,AccountNumber

【问题讨论】:

    标签: sql sql-server tsql select


    【解决方案1】:

    这样查询。您可以计算不同的值。 当您计算唯一值时,列“Three_Unique_Cat”。当您准确计算“cat1”、“cat2”、“cat3”时,列“Three_Cat1_Cat2_Cat3”

    SELECT 
        EOMONTH, AccountNumber
        ,CASE WHEN
           COUNT(DISTINCT CLASSIFICATION_NAME)=3 THEN 1 
           ELSE 0 
        END AS 'Three_Unique_Cat'
        ,CASE WHEN 
           COUNT(DISTINCT CASE WHEN CLASSIFICATION_NAME IN ('cat1','cat2','cat3') 
            THEN CLASSIFICATION_NAME ELSE NULL END)=3 THEN 1 
           ELSE 0 
         END AS 'Three_Cat1_Cat2_Cat3'
        ,SUM(Value) AS totalSpend
    FROM @tran_TABLE
    GROUP BY EOMONTH, AccountNumber 
    
    Output:
    EOMONTH   AccountNumber Three_Unique_Cat    Three_Cat1_Cat2_Cat3    totalSpend
    2018-11-30  123 1   1   52
    2019-01-31  123 1   1   37
    2019-03-31  123 0   0   15
    
    

    【讨论】:

      【解决方案2】:

      很简单,如下:

      select
          EOMONTH,
          AccountNumber,
          case when count(distinct CLASSIFICATION_NAME) = 3 then 1 else 0 end as CLASSIFICATION_NAME
      from
          tran_TABLE
      group by
          EOMONTH,
          AccountNumber
      

      【讨论】:

      • 这对@mkRabbani 发布的基本相同的答案增加了什么?
      • 好的,我明白了。当我编辑此答案时,此页面尚未更新。
      【解决方案3】:

      您可以通过计算满足此条件的不同分类(每组)来模拟此行为:

      SELECT 
          EOMONTH
          ,AccountNumber
          ,CASE COUNT(DISTINCT CASE WHEN classification_name IN ('cat1', 'cat2', 'cat3') THEN classification_name END) 
                WHEN 3 THEN 1 
                ELSE 0 
           END
          ,SUM(Value) AS totalSpend
      FROM @tran_TABLE
      GROUP BY 
          EOMONTH
          ,AccountNumber
      

      【讨论】:

      【解决方案4】:

      试试这个-

      SELECT EOMONTH, 
      AccountNumber,
      CASE 
          WHEN COUNT(DISTINCT CLASSIFICATION_NAME) = 3 THEN 1
          ELSE 0
      END CLASSIFICATION_NAME
      FROM @tran_TABLE
      GROUP BY EOMONTH,AccountNumber
      

      输出是-

      2018-11-30  123 1
      2019-01-31  123 1
      2019-03-31  123 0
      

      【讨论】:

      • 只有在 cat1、cat2 和 cat3 之外没有其他分类的情况下才有效。如果可能的话,您将需要另一个条件 - 有关详细信息,请参阅我的答案。
      • @Mureinik 您只需将数字 3 更新为您的分类总数。除非您管理单独的分类列表,否则无法使其动态化。在您的解决方案中,您必须更改分类列表以及在发生更改时使用的数字 3。事实上,您和我的解决方案几乎相同。
      • 另外@Mureinik - 如果在分类列表中添加了新的 Cat4,您的解决方案也将不起作用,对吧?
      猜你喜欢
      • 2021-10-21
      • 2011-09-25
      • 2018-03-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-14
      • 2015-10-14
      • 1970-01-01
      相关资源
      最近更新 更多