Удаление группы результатов, если всего 0 - PullRequest
0 голосов
/ 13 мая 2019

Я использую следующую таблицу для создания гистограммы с накоплением - она ​​немного больше, чем эта:

ID | Name | foodEaten | total
1  | Sam  | Burger    | 3
1  | Sam  | Pizza     | 1
1  | Sam  | Kebab     | 0
1  | Sam  | Cheesecake| 3
1  | Sam  | Sandwich  | 5
2  | Jeff | Burger    | 0
2  | Jeff | Pizza     | 0
2  | Jeff | Kebab     | 0
2  | Jeff | Cheesecake| 0
2  | Jeff | Sandwich  | 0

Мне нужно найти способ удалить результаты, такие как Джефф.Где общая сумма того, что он съел, равна 0. Я не могу придумать самый простой способ достичь этого.Я попытался сгруппировать весь результат по идентификатору и создать общее значение, но этого просто не происходит.

Если человек съел в общей сложности 0 ед, его нужно исключить.Но если он этого не сделал, и он не ел кебабы, как показано в моей таблице выше, это должно быть включено в результат!

Таким образом, необходим вывод:

ID | Name | foodEaten | total
1  | Sam  | Burger    | 3
1  | Sam  | Pizza     | 1
1  | Sam  | Kebab     | 0
1  | Sam  | Cheesecake| 3
1  | Sam  | Sandwich  | 5

Ответы [ 6 ]

2 голосов
/ 13 мая 2019

Предполагая, что вам нужны данные в том виде, в котором они отображаются, а не агрегат, а затем исключите:

WITH CTE AS (
    SELECT ID,
           [Name],
           foodEaten,
           total,
           SUM(total) OVER (PARTITION BY [Name]) AS nameTotal
    FROM YourTable)
SELECT ID,
       [Name],
       foodEaten,
       total
FROM CTE
WHERE nameTotal > 0;
0 голосов
/ 13 мая 2019

Предполагая, что total никогда не бывает отрицательным, тогда, вероятно, наиболее эффективным методом является использование exists:

select t.*
from t
where exists (select 1
              from t t2
              where t2.name = t.name and
                    t2.total > 0
             );

В частности, для этого может быть использован индекс на (name, total).

0 голосов
/ 13 мая 2019

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

;WITH CTE (ID , Name , foodEaten , total)
AS
(
SELECT 1  , 'Sam'  , 'Burger'    , 3 UNION ALL
SELECT 1  , 'Sam'  , 'Pizza'     , 1 UNION ALL
SELECT 1  , 'Sam'  , 'Kebab'     , 2 UNION ALL
SELECT 1  , 'Sam'  , 'Cheesecake', 3 UNION ALL
SELECT 1  , 'Sam'  , 'Sandwich'  , 5 UNION ALL
SELECT 2  , 'Jeff' , 'Burger'    , 0 UNION ALL
SELECT 2  , 'Jeff' , 'Pizza'     , 0 UNION ALL
SELECT 2  , 'Jeff' , 'Kebab'     , 0 UNION ALL
SELECT 2  , 'Jeff' , 'Cheesecake', 0 UNION ALL
SELECT 2  , 'Jeff' , 'Sandwich'  , 0
)
SELECT ID , Name ,SUM( total)  AS Grandtotal
FROM CTE
GROUP BY  ID , Name 
HAVING SUM( total) >0

Результат

ID  Name    Grandtotal
----------------------
1   Sam         14
0 голосов
/ 13 мая 2019

Использование DELETE с HAVING SUM(total) = 0 удалит группу результатов, итоговая сумма которых равна 0

DELETE FROM TableName
WHERE ID IN (SELECT Id FROM TableName GROUP BY ID HAVING SUM(total) = 0)

или, если вы хотите выполнить реввое и выбрать только те записи, сумма которых равна нулю,тогда

SELECT * FROM TableName
WHERE ID NOT IN (SELECT Id FROM TableName GROUP BY ID HAVING SUM(total) = 0)
0 голосов
/ 13 мая 2019
select id, name, foodEaten, sum(total) as total from <table> group by ID having sum(total) > 0

Это работает для вас?

0 голосов
/ 13 мая 2019

Вы можете попробовать ниже -

select id,name
from tablename a
group by id,name
having sum(total)>0 

ИЛИ

DEMO

select * from tablename a 
where not exists (select 1 from tablename b where a.id=b.id group by id,name
having sum(total)=0)
...