SQL: join returns 多个匹配只删除一行
SQL: Delete only one row if join returns multiple matches
我有一个 SQL table,如下所示:
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
您可以使用 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
);
我认为您可以通过向联接添加条件来简化查询:
DELETE T1
FROM #testable T1
INNER JOIN #testable T2 ON T1.col1 = T2.col2 AND T1.col2 = T2.col1 AND T1.col1 > T1.col2
假设没有实际重复,我会这样做:
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
所在的行,但前提是 "paired" 行已经存在于 table.
我有一个 SQL table,如下所示:
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
您可以使用 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
);
我认为您可以通过向联接添加条件来简化查询:
DELETE T1
FROM #testable T1
INNER JOIN #testable T2 ON T1.col1 = T2.col2 AND T1.col2 = T2.col1 AND T1.col1 > T1.col2
假设没有实际重复,我会这样做:
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
所在的行,但前提是 "paired" 行已经存在于 table.