我在编写脚本时遇到问题,该脚本可以删除前三列匹配的所有行以及数量总和为零的行? 我认为查询需要查找匹配的所有产品,然后在该组内,找到匹配的所有名称,然后在该子集内,匹配的所有货币,然后是数量净额为零的货币。
在下面的示例中,要删除的行将是第1行和第2行以及第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
希望这是有道理的,并感谢任何帮助。
答案 0 :(得分: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
)
答案 1 :(得分: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);
答案 2 :(得分: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)
答案 3 :(得分:0)
我假设这是一个会计问题,在分类帐中抵消了一对条目。
如果组合(A,A,GBP)有三个条目,则此代码和上面的一些示例将不起作用。
我创建了一个临时测试表,用数据加载它,使用CTE - 公用表表达式 - 找到重复模式并将其连接到表中以选择行。
只需将'select *'更改为'delete'。
同样,这仅适用于相等的偏移对。它将导致奇数条目的破坏。
您是否只有偶数条目?
此致
约翰
-- 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;