例如,我有一个带有值的简单表:
|Code|Value|
|x1 |5 |
|x2 |-5 |
|x3 |-5 |
|x4 |5 |
|x5 |5 |
我需要删除总和等于0的行。 即对于这个例子,我想要删除代码为x1和x2,x3和x4或x1和x2,x3和x5的行 - 在我的情况下并不重要。
这听起来很简单,但我不能这样做 我甚至不明白如何选择我想要删除的项目。
我试着像这样连接表:
SELECT
t1.Code AS Code1,
t2.Code AS Code2
FROM TableX AS t1
JOIN TableX As t2
ON t1.Code <> t2.Code
AND t1.Value + t2.Value = 0
ORDER BY t1.Code
结果:
|Code1|Code2
|x1 |x2
|x1 |x3
|x2 |x1
|x2 |x4
|x2 |x5
|x3 |x1
|x3 |x4
|x3 |x5
|x4 |x2
|x4 |x3
|x5 |x2
|x5 |x3
但我不明白接下来该怎么做。
我不是懒惰 - 我尝试了不同的变体 - 使用GROUP BY和MIN,使用ROW_NUMBER()但不幸的是我无法理解如何选择要删除的行并留下其他行?
答案 0 :(得分:4)
这似乎涵盖了它,我相信:
declare @t table (Code varchar(20) not null, Value int not null)
insert into @t(Code,Value) values
('x1',5 ),
('x2',-5 ),
('x3',-5 ),
('x4',5 ),
('x5',5 )
;With Ordered as (
select
Code,
Value,
ROW_NUMBER() OVER (PARTITION BY Value ORDER BY Code) rn
from
@t
), Pairs as (
select
o1.Code c1,
o2.Code c2
from
Ordered o1
inner join
Ordered o2
on
o1.Value = -o2.Value and
o1.rn = o2.rn
where
o1.Value > 0
)
delete from t from @t t where exists (
select * from Pairs p where p.c1 = t.Code or
p.c2 = t.Code)
select * from @t
结果:
Code Value
-------------------- -----------
x5 5
这可以决定根据Value
的内容为每一行提供唯一的行号。然后,我们根据查找行数相等但值相反的行来配对行。
select * from Ordered
或select * from Pairs
而不是delete
,如果你想了解它是如何运作的话,可能会有所帮助。