【问题标题】:SQL: Delete only one row if join returns multiple matchesSQL:如果连接返回多个匹配项,则仅删除一行
【发布时间】:2018-12-17 10:32:11
【问题描述】:

我有一个如下所示的 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

【问题讨论】:

    标签: sql-server tsql join sql-delete


    【解决方案1】:

    我认为您可以通过向联接添加条件来简化查询:

        DELETE T1
        FROM #testable T1
            INNER JOIN #testable T2 ON T1.col1 = T2.col2 AND T1.col2 = T2.col1 AND T1.col1 > T1.col2
    

    【讨论】:

      【解决方案2】:

      你可以使用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
                    );
      

      【讨论】:

        【解决方案3】:

        假设没有实际重复,我会这样做:

        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 &gt; col2所在的行,但前提是表中已存在“配对”行。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-01-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-02-18
          • 1970-01-01
          相关资源
          最近更新 更多