Reputation: 492
Say I have a table like this called inventory, for example:
+----+------------+-------+
| id |Product_ID | Count |
+----+------------+-------+
| 1 | 1 | 4 |
| 2 | 2 | 5 |
| 3 | 4 | 3 |
| 4 | 5 | 3 |
| 5 | 5 | -3 |
| 6 | 2 | -5 |
+----+------------+-------+
And the result of my query GroupedInventory AS (SELECT id, Product_ID, Count FROM inventory ORDER BY Product_ID gives me (stored in GroupedInventory):
+----+------------+-------+
| id |Product_ID | Count |
+----+------------+-------+
| 1 | 1 | 4 |
| 2 | 2 | 5 |
| 6 | 2 | -5 |
| 3 | 4 | 3 |
| 4 | 5 | 3 |
| 5 | 5 | -3 |
+----+------------+-------+
And I want to delete the matching positive and negative results. So in the end the table should turn into:
+----+------------+-------+
| id |Product_ID | Count |
+----+------------+-------+
| 1 | 1 | 4 |
| 3 | 4 | 3 |
+----+------------+-------+
I deal with sequential languages and I just can't wrap my head around this. My mind is telling me to loop through the table, store the pairs and then delete the pairs by id in the original table.
Upvotes: 0
Views: 252
Reputation: 69
with GroupedInventory as
(
SELECT Product_id, abs(sum(case when count < 0 then count else 0 end)) Negative, abs(sum(case when count > 0 then count else 0 end)) Positive
FROM inventory
group by Product_id
)
delete from inventory
where Product_id in (select Product_id from GroupedInventory where positive = negative );
Although the validity also depends on unspecified rules, such as how many entries can exist for a given product_id.
Upvotes: 1
Reputation: 907
Try this one
DELETE inventory
FROM inventory
INNER JOIN (
SELECT Product_ID FROM inventory group by Product_ID HAVING SUM(Count)=0
) as t ON inventory.Product_ID = t.Product_ID
Upvotes: 0
Reputation: 8892
You can try using the OVER
clause with PARTITION BY
AS well, You can read it here.
Here is the query with your given test data,
create table #temp
(id bigint,
proid bigint,
cnt bigint)
insert into #temp
values(1,1,4),
(2,2,5),
(3,4,3),
(4,5,3),
(5,5,-3),
(6,2,-5)
;WITH cte
AS(
SELECT id, proid, SUM(cnt) OVER(PARTITION BY proid) AS total
FROM #temp
)
SELECT *
FROM cte
WHERE total <> 0
Drop table #temp
Upvotes: 0
Reputation: 1723
Use this uqery:
SELECT
MIN(GI.ID) AS ID, GI.Product_ID, SUM(GI.Count) As COUNT
FROM
GroupedInventory AS GI
GROUP BY
GI.Product_ID
HAVING
SUM(GI.Count) <> 0;
I use MIN
and SUM
so as result you will have calculation of sum grouped to MIN
ID. I don't know if this is desired result. It is not clear.
Upvotes: 0
Reputation: 400
Try this:
SELECT id, Product_ID, SUM(Count)
FROM [GroupedInventory]
WHERE SUM(Count) <> 0
GROUP BY Product_ID, id
I'm not 100% positive that will work without testing it myself, let me know if you get a weird result.
Upvotes: 0