Sql删除语句故障
我在编写一个脚本时遇到了问题,该脚本可以删除前三列上匹配的所有行,并且数量总和为零? 我认为查询需要找到所有匹配的产品,然后在该组中,所有匹配的名称,然后在该子集中,所有匹配的货币,然后是数量为零的货币 在下面的示例中,要删除的行是第1行和第2行、第4行和第6行Sql删除语句故障,sql,sql-server,Sql,Sql Server,我在编写一个脚本时遇到了问题,该脚本可以删除前三列上匹配的所有行,并且数量总和为零? 我认为查询需要找到所有匹配的产品,然后在该组中,所有匹配的名称,然后在该子集中,所有匹配的货币,然后是数量为零的货币 在下面的示例中,要删除的行是第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,
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
希望这有意义,并感谢您的帮助。尝试以下方法:
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
)
简化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)
你可能想把这个问题分成几个部分 首先创建一个视图,列出总和为零的组合
CREATE VIEW vw_foo AS
SELECT product,name, currency, sum(quantity) as net
FROM foo
GROUP BY product, name, currency
HAVING sum(quantity)=0;
此时,您需要确保此视图包含您希望删除的数据。在您的示例中,视图应该只有两条记录:ProductA/NameA/GBP和ProductA/NameB/USD
第二步。删除字段匹配的数据:
DELETE FROM foo
WHERE EXISTS
(SELECT *
FROM vw_foo
WHERE vw_foo.product = product
AND vw_foo.name = name
AND vw_currency = currency);
我假设这是一个会计问题,需要抵销分类账中的成对分录 例如,如果组合有三个条目(A、A、GBP),则此代码和上面的一些示例将不起作用 我创建了一个临时测试表,加载了您的数据,使用CTE(公共表表达式)来查找重复模式,并将其连接到表中以选择行 只需将“选择*”更改为“删除” 同样,这只适用于相等的偏移对。它将导致奇数个条目的混乱 您是否只有偶数个条目 诚恳 约翰
除非您添加一些约束,否则这就是子集和问题,这是NP-难的。总是有偏移行吗?例如,如果您的产品/名称货币有三个值-20、-10和30,该怎么办?它们都应该被删除,或者30的记录可能在等待-30吗?@Jerry,不应该有三行产品、名称和货币的值相同的情况。我喜欢它,而且它不仅仅是sql server。请注意,“foo”+“bar”很像“foob”+“ar”。匹配连接并不意味着匹配列。@哈波,我敢打赌OP的数据中没有冲突。谢谢波希米亚人,工作得很好!。虽然Habo提到的问题不应该是个问题,但为了以防万一,我在连接中添加了空格。
-- 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;