在SQL中是否有可能删除(只有一个)组合列的重复条目(这里:city,zip)?所以,如果我有这个SQL:
INSERT INTO foo (id, city, zip) VALUES (1, 'New York', '00000')
INSERT INTO foo (id, city, zip) VALUES (2, 'New York', '00000')
我可以稍后用sql语句删除第一个吗?我的方法不适合那个
DELETE FROM foo (id, city, zip)
WHERE id IN
(SELECT id FROM foo GROUP BY id HAVING (COUNT(zip) > 1))
答案 0 :(得分:6)
改编自this article。这两个解决方案是通用的,应该适用于任何合理的SQL实现。
DELETE T1
FROM foo T1, foo T2
WHERE (T1.city = T2.city AND foo1.zip=foo2.zip) -- Duplicate rows
AND T1.id > T2.id; -- Delete the one with higher id
简单,对于没有重复的小表或表,应该可以正常工作。
CREATE TABLE foo_temp LIKE(foo);
INSERT INTO foo_temp (SELECT distinct city, zip) FORM foo;
TRUNCATE TABLE foo;
如果你有幸将序列作为你的身份证,那么,只需:
INSERT INTO foo SELECT * FROM foo_temp;
DROP TABLE foo_temp;
有点复杂,但对于具有大量重复的非常大的表非常有效。对于这些,为(city,zip)创建索引将极大地提高查询性能。
答案 1 :(得分:2)
在SQL Server 2005
及更高版本中:
WITH q AS
(
SELECT *,
ROW_NUMBER() OVER (PARTITION BY city, zip ORDER BY id) AS rn,
COUNT(*) OVER (PARTITION BY city, zip ORDER BY id) AS cnt
FROM mytable
)
DELETE
FROM q
WHERE rn = 1
AND cnt > 1
删除第一行(具有重复项),
WITH q AS
(
SELECT *, ROW_NUMBER() OVER (PARTITION BY city, zip ORDER BY id) AS rn
FROM mytable
)
DELETE
FROM q
WHERE rn = 2
删除第一个副本,
WITH q AS
(
SELECT *, ROW_NUMBER() OVER (PARTITION BY city, zip ORDER BY id) AS rn
FROM mytable
)
DELETE
FROM q
WHERE rn > 1
删除所有重复项。
答案 2 :(得分:1)
目前尚不清楚您的情况下支持哪种SQL,因为不同的方言具有不同的功能。我想到的是在内部查询中使用zip
上的排名而不是HAVING
,并且只包含排名为>的排名。 1。
答案 3 :(得分:1)
DELETE FROM
cities
WHERE
id
NOT IN
(
SELECT id FROM
(
-- Get the maximum id of any zip / city combination
-- This will work with both duped and non-duped rows
SELECT
MAX(id),
city,
zip
FROM
cities
GROUP BY
city,
zip
) ids_only
)
答案 4 :(得分:0)
接受的答案对我的oracle db没有影响。 这样做了:
@using Microsoft.AspNetCore.Http;
@Context.Request.Cookies.Get("Bearer")
(也适用于任何列而不是rowid。)
找到here。