Использование EXISTS в предложении GROUP BY - PullRequest
7 голосов
/ 16 мая 2019

Можно ли сделать следующее:
У меня есть таблица, которая выглядит следующим образом:

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

Ответы [ 4 ]

7 голосов
/ 16 мая 2019

Вы могли бы подражать этому поведению, посчитав различные классификации, которые отвечают этому условию (на группу):

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
1 голос
/ 16 мая 2019

Запрос такой.Вы можете посчитать разные значения.Когда вы подсчитываете уникальные значения, тогда столбец 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

1 голос
/ 16 мая 2019

Попробуйте это-

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
0 голосов
/ 16 мая 2019

Это просто, как показано ниже:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...