我有一个如下所示的SQL表:
col1 col2
a b
b a
c d
d c
f g
如您所见,存在行col1
和col2
都被反转的行。我的意思是,第一行的值a
和b
都在两列中,而在第2行的值也都在那儿,但是相反。
我现在想删除每个对中的一行。我不在乎该对的哪一边被删除。因此,应该删除第1行和第3行或第2行和第4行。
结果应如下所示:
col1 col2
a b
c d
f g
或
col1 col2
b a
d c
f g
我通过以下查询实现了这一点,该查询创建了两个人工列,它们按排序顺序包含值,然后应用GROUP BY
,但我认为应该有一个更好看的解决方案。
DELETE t1
FROM testtable t1
INNER JOIN (
SELECT CASE WHEN col1 < col2 THEN col1 ELSE col2 END AS first,
CASE WHEN col1 < col2 THEN col2 ELSE col1 END AS second
FROM testtable
GROUP BY CASE WHEN col1 < col2 THEN col1 ELSE col2 END, CASE WHEN col1 < col2 THEN col2 ELSE col1 END
) t2 ON t2.first = t1.col1 AND t2.second = t1.col2
答案 0 :(得分:2)
我认为您可以通过为连接添加条件来简化查询:
DELETE T1
FROM #testable T1
INNER JOIN #testable T2 ON T1.col1 = T2.col2 AND T1.col2 = T2.col1 AND T1.col1 > T1.col2
答案 1 :(得分:0)
您可以使用exists
和not exists
:
select t.*
from testtable t
where exists (select 1
from testtable t1
where t1.col1 > t.col1 and t1.col1 = t.col2
) or
not exists (select 1
from testtable t1
where t1.col1 < t.col1 and t1.col1 = t.col2
);
如果您要删除不需要的记录,则可以执行以下操作:
delete t
from testtable t
where not exists (select 1
from testtable t1
where t1.col1 > t.col1 and t1.col1 = t.col2
) and
exists (select 1
from testtable t1
where t1.col1 < t.col1 and t1.col1 = t.col2
);
答案 2 :(得分:0)
假设没有实际重复,我会这样做:
delete t from testtable t
where col1 > col2 and
exists (select 1
from testtable t2
where t2.col1 = t.col2 and t2.col2 = t.col1
);
也就是说,仅在表中已经存在“配对”行的情况下,删除col1 > col2
所在的行。