SQL:如果联接返回多个匹配项,则仅删除一行

时间:2018-12-17 10:32:11

标签: sql-server tsql join sql-delete

我有一个如下所示的SQL表:

col1   col2
a      b
b      a
c      d
d      c
f      g

如您所见,存在行col1col2都被反转的行。我的意思是,第一行的值ab都在两列中,而在第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

3 个答案:

答案 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)

您可以使用existsnot 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所在的行。