我正在尝试从名为[dbo].[FactGunSales]
的表中删除一些重复的日期,并且该列为[sale_id]
。我正在检查下面的代码是否存在重复项,该代码是否有效,然后下面的代码是我遇到的代码,因为它不影响任何行。
-- Detecting Duplicate
SELECT [sale_id], COUNT(*) TotalCount
FROM [dbo].[FactGunSales]
GROUP BY [sale_id]
HAVING COUNT(*) > 1
ORDER BY COUNT(*) DESC
GO
-- Deleting Duplicate
DELETE FROM [dbo].[FactGunSales]
WHERE [sale_id] NOT IN (SELECT MAX([sale_id])
FROM [dbo].[FactGunSales]
GROUP BY [sale_id])
GO
任何帮助都会很棒
答案 0 :(得分:4)
使用not exists
:
请使用ROW_NUMBER()
或COUNT(*)
。您的代码似乎等同于:
WITH todelete AS (
SELECT fgs.*, COUNT(*) OVER (PARTITION BY sale_id) as cnt
FROM [dbo].[FactGunSales] fgs
)
DELETE FROM to_delete
WHERE cnt > 1;
不过,通常情况下,您不想删除所有 个重复项。您想保留其中之一。为此,请使用ROW_NUMBER()
:
WITH todelete AS (
SELECT fgs.*, ROW_NUMBER() OVER (PARTITION BY sale_id ORDER BY sale_id) as seqnum
FROM [dbo].[FactGunSales] fgs
)
DELETE FROM to_delete
WHERE seqnum > 1;
您的查询没有提供关于要保留哪个行的指示。此版本保留任意行。您可以通过更改ORDER BY
子句来保持最新或最旧或最大或最小或任何其他值。
您的版本不会删除任何内容,因为sale_id
的至少一个值为NULL
。如果子查询返回的 any 值为NULL
,则WHERE
会过滤掉所有行。通常,我强烈建议改用NOT EXISTS
,但为此目的,更新CTE更具意义。
答案 1 :(得分:0)
您可以考虑使用cte并根据sale_id对记录进行排名,因此任何重复的sale_id将具有rank = 2,3,4等。之后,您需要删除<> rank的条目= 1
(defparameter *ht-2* (make-hash-table :test 'equal))
(setf (gethash *key* *ht-2*) 20)
*ht-2*
==> #S(HASH-TABLE :TEST FASTHASH-EQUAL ((42) . 20))
(gethash *key* *ht-2*)
==> 20; T
(setf (car *key*) 7) ; **visible modification**!
(gethash '(7) *ht-2*)
==> unspecified!
(gethash *key* *ht-2*)
==> unspecified!
(setf (car *key*) 42) ; restore key
(gethash '(42) *ht-2*)
==> unspecified!
(gethash *key* *ht-2*)
==> unspecified!