У меня есть таблица с именами, типами и значениями.Использование предложения HAVING для идентификации групп с определенной комбинацией записей
DECLARE @t_Table TABLE
(
Name VARCHAR(10),
[Type] VARCHAR(10),
Value INT
)
INSERT INTO @t_Table
VALUES('Jill', 'Yellow', 100)
INSERT INTO @t_Table
VALUES('Jill', 'Blue', 200)
INSERT INTO @t_Table
VALUES('Jill', 'Green', 300)
INSERT INTO @t_Table
VALUES('Jill', 'Green', 400)
INSERT INTO @t_Table
VALUES('Jill', 'Green', 500)
INSERT INTO @t_Table
VALUES('Bob', 'Yellow', 100)
INSERT INTO @t_Table
VALUES('Bob', 'Blue', 200)
INSERT INTO @t_Table
VALUES('Bob', 'Green', 300)
INSERT INTO @t_Table
VALUES('Bob', 'Orange', 400)
INSERT INTO @t_Table
VALUES('Bob', 'Orange', 400)
INSERT INTO @t_Table
VALUES('Bob', 'Purple', 500)
INSERT INTO @t_Table
VALUES('Steve', 'Yellow', 100)
INSERT INTO @t_Table
VALUES('Steve', 'Blue', 200)
INSERT INTO @t_Table
VALUES('Steve', 'Green', 300)
INSERT INTO @t_Table
VALUES('Steve', 'Orange', 400)
INSERT INTO @t_Table
VALUES('Steve', 'Orange', 400)
Я хочу, чтобы получить общее значение для групп имен, где основные записи в группе удовлетворяют ограничение на возникновении определенных типов. Я хочу выполнить это с помощью одного агрегата в предложении HAVING.
В случае, когда я хочу группу ровно с одной записью типа х, ровно одна запись типа у, ноль или несколько записей типа г и никаких других записей, я прибыл в следующем растворе, например, когда я хочу точно один желтый, один синий и ноль или более зеленый:
SELECT Name,
TotalValue = SUM(Value)
FROM @t_Table
GROUP BY Name
HAVING SUM(CASE WHEN [Type] = 'Yellow' THEN 1
WHEN [Type] = 'Blue' THEN 2
WHEN [Type] = 'Green' THEN 0
ELSE 4 END) = 3
Что правильно возвращает этот результат:
Name TotalValue
---------- -----------
Jill 1500
Как я могу построить следующее?
SELECT Name,
TotalValue = SUM(Value)
FROM @t_Table
GROUP BY Name
/*HAVING exactly one record with [Type] = 'Yellow'
and exactly one record with [Type] = 'Blue'
and exactly one record with [Type] = 'Green'
and zero or more records with [Type] = 'Orange'
and no records of any other type
*/
Если ожидаемый результат, учитывая данные выше, будет
Name TotalValue
---------- -----------
Steve 1400
Я знаю следующее решения (ниже), но мне нужен тот, который имеет один агрегат в предложении HAVING
. Я также открыт для другой структуры запросов, которая решает мою проблему, если она такая же простая или простая, как и предлагаемая мной структура, и работает аналогично или лучше.
SELECT
Name,
TotalValue = SUM(Value)
FROM
@t_Table
GROUP BY
Name
HAVING
SUM(CASE WHEN [Type] = 'Yellow' THEN 1 ELSE NULL END) = 1
AND SUM(CASE WHEN [Type] = 'Blue' THEN 1 ELSE NULL END) = 1
AND SUM(CASE WHEN [Type] = 'Green' THEN 1 ELSE NULL END) = 1
AND SUM(CASE WHEN [Type] IN ('Yellow','Blue','Green','Orange') THEN 0 ELSE 1 END) = 0
Просто синтаксический сахар 'IIF' но сделать его короче' ВЫБРАТЬ Имя, TotalValue = SUM (Value) ОТ @t_Table GROUP BY имя HAVING SUM (IIF ([Тип] = 'желтый', 1, NULL)) = 1 И СУММ (IIF ([Тип] = 'Синий', 1, NULL)) = 1 И СУММ (IIF ([Тип] = 'Зеленый', 1, NULL)) = 1 И СУММ (IIF ([Type] IN («Желтый», «Синий», «Зеленый», «Оранжевый»), 0,1)) = 0' – lad2025
Следует отметить, что IIF применяется только к SQL Server 2014 и более поздним. – rwking
@rwking Следует отметить, что ** IIF применяется к SQL Server 2012 +. ** – lad2025