考虑没有任何主键或外键的表。 我想编写一个过程,它将删除给定表名的所有重复行。
如果所有字段都相同,则该行应被视为与其他行重复。
如果可能的话,你能建议我吗?我尝试的一件事是按每个领域分组,但这种方法并不普遍。
答案 0 :(得分:5)
您可以使用Dynamic-SQL实现它
快速支持的解决方案(很大的改进空间):
CREATE TABLE tab1(a INT, b INT);
INSERT INTO tab1(a,b) VALUES (1,1),(1,1),(1,1),(2,3);
GO
步骤:
CREATE PROCEDURE dbo.remove_duplicates
@tab_name SYSNAME
,@debug BIT = 0
AS
BEGIN
SET NOCOUNT ON;
-- TODO: validation if table does not exist, raise error
-- TODO: Add @schema parameter
-- TODO: Wrap with BEGIN TRY, omit calculated columns, CAST `TEXT/IMAGE/BINARY`....
DECLARE @sql NVARCHAR(MAX) =
'WITH cte AS
(
SELECT *, rn = ROW_NUMBER() OVER(PARTITION BY <cols> ORDER BY (SELECT 1))
FROM <tab_placeholder>
)
DELETE FROM cte
WHERE rn <> 1;';
DECLARE @cols NVARCHAR(MAX) = STUFF((SELECT ',' + column_name
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = @tab_name
AND TABLE_SCHEMA = 'dbo'
FOR XML PATH('')), 1, 1, '');
SET @sql = REPLACE(@sql, '<tab_placeholder>', QUOTENAME(@tab_name));
SET @sql = REPLACE(@sql, '<cols>', @cols);
IF @debug = 1 SELECT @sql;
EXEC dbo.sp_executesql @sql;
END
GO
执行:
EXEC [dbo].[remove_duplicates] @tab_name = 'tab1', @debug = 1;
SELECT * FROM tab1;
的 LiveDemo
强>
答案 1 :(得分:0)
这将从表中删除重复项。您的分区必须包含您希望分组的字段,以确定重复的内容。在你的情况下,所有这些。
IF OBJECT_ID('tempdb..#TABLE') IS NOT NULL DROP TABLE #TABLE
CREATE TABLE #TABLE ( SOMEINT INT,SOMEVALUE VARCHAR(255) )
INSERT INTO #TABLE ( SOMEINT, SOMEVALUE )
VALUES (1,'VALUE1')
,(1,'VALUE2')
,(1,'VALUE2')
,(1,'VALUE3')
,(1,'VALUE4')
,(1,'VALUE4')
,(1,'VALUE4')
,(1,'VALUE4')
,(1,'VALUE5')
,(1,'VALUE6')
,(1,'VALUE6')
,(1,'VALUE6')
,(1,'VALUE7')
,(1,'VALUE8')
,(1,'VALUE8')
,(1,'VALUE9')
,(1,'VALUE10')
;WITH dedup
AS
(
SELECT *, ROW_NUMBER() OVER (PARTITION BY SOMEINT,SOMEVALUE ORDER BY SOMEINT ASC) AS SEQUENCE
FROM #TABLE
)
DELETE
FROM dedup
WHERE SEQUENCE > 1
GO
SELECT * FROM #TABLE
答案 2 :(得分:0)
有多种方式
首先,
创建临时表,并将不同的数据复制到该临时表。删除或截断实际表中的数据。并将临时表复制到您的实际表中。删除临时表
SELECT DISTINCT * INTO #table1 from TABLE1
DELETE FROM TABLE1
INSERT INTO TABLE1
SELECT * FROM #table1
DROP TABLE #table1
或
其次,
向表中添加一列,使用ROW_NUMBER PARTITION更新该列,然后删除COLUMN&lt;&gt;中的行1。删除新创建的列。