删除总和等于0的行

时间:2016-06-24 13:40:16

标签: sql sql-server tsql

例如,我有一个带有值的简单表:

|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()但不幸的是我无法理解如何选择要删除的行并留下其他行?

1 个答案:

答案 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 Orderedselect * from Pairs而不是delete,如果你想了解它是如何运作的话,可能会有所帮助。