1

I am having trouble writing a script which can delete all the rows which match on the first three columns and where the Quantities sum to zero? I think the query needs to find all Products that match and then within that group, all the Names which match and then within that subset, all the currencies which match and then, the ones which have quantities netting to zero.

In the below example, the rows which would be deleted would be rows 1&2,4&6.

Product, Name, Currency, Quantity

1) Product A, Name A, GBP, 10
2) Product A, Name A, GBP, -10
3) Product A, Name B, GBP, 10
4) Product A, Name B, USD, 10
5) Product A, Name B, EUR, 10
6) Product A, Name B, USD, -10
7) Product A, Name C, EUR, 10

Hope this makes sense and appreciate any help.

4

4 回答 4

1

尝试这个:

DELETE  
  FROM [Product]
 WHERE Id IN
(
SELECT Id
  FROM 
(
   SELECT Id, SUM(Quantity) OVER(PARTITION BY a.Product, a.Name, a.Currency) AS Sm
    FROM [Product] a

) a
WHERE Sm = 0
)
于 2013-09-27T23:58:45.177 回答
1

您可能希望将此问题分解为多个部分。

首先创建一个视图,列出总和为零的那些组合

CREATE VIEW vw_foo AS
SELECT product,name, currency, sum(quantity) as net
FROM foo
GROUP BY product, name, currency
HAVING sum(quantity)=0;

此时,您需要确保此视图具有您希望删除的数据。在您的示例中,视图应该只有 2 条记录:ProductA/NameA/GBP 和 ProductA/NameB/USD

步骤 2. 删除字段匹配的数据:

DELETE FROM foo
WHERE EXISTS 
(SELECT *
FROM vw_foo
WHERE vw_foo.product = product
AND vw_foo.name = name
AND vw_currency = currency);
于 2013-09-28T00:10:05.583 回答
0

我假设这是一个会计问题,抵消了分类帐中的条目对。

例如,如果有三个组合条目(A、A、GBP),则此代码和上面的某些示例将不起作用。

我创建了一个临时测试表,将您的数据加载到其中,使用 CTE(通用表表达式)来查找重复模式并将其连接到表中以选择行。

只需将“选择 *”更改为“删除”即可。

同样,这仅适用于相等的偏移对。这将导致奇数条目造成严重破坏。

你只有偶数个条目吗?

真挚地

约翰

-- create sample table
create table #products
(
  product_id int identity(1,1),
  product_txt varchar(16), 
  name_txt varchar(16), 
  currency_cd varchar(16), 
  quantity_num int
);
go

-- add data 2 table
insert into #products
(product_txt, name_txt, currency_cd, quantity_num)
values
('A',  'A', 'GBP', 10),
('A',  'A', 'GBP', -10),
('A',  'B', 'GBP', 10),
('A',  'B', 'USD', 10),
('A',  'B', 'EUR', 10),
('A',  'B', 'USD', -10),
('A',  'C', 'EUR', 10);
go

-- show the data
select * from #products;
go

-- use cte to find combinations
with cte_Ledger_Offsets (product_txt, name_txt, currency_cd)
as
(
    select product_txt, name_txt, currency_cd
    from #products
    group by  product_txt, name_txt, currency_cd
    having sum(quantity_num) = 0
)
select * from #products p inner join cte_Ledger_Offsets c
on p.product_txt = c.product_txt and
p.name_txt = c.name_txt and 
p.currency_cd = c.currency_cd;
于 2013-09-28T00:35:29.177 回答
0

简化 SQL 的一种方法是将 3 列连接为一列并应用一些分组:

delete from product
where product + name + currency in (
    select product + name + currency
    from product
    group by product + name + currency
    having sum(quantity) = 0)
于 2013-09-28T00:03:56.573 回答