我知道如何使用CTE删除重复记录。
如何在不使用CTE [面试问题]的情况下实现这一目标
有可能吗?
示例:包含以下数据的表:
name salary
-----------------
Husain 20000.00
Husain 20000.00
Husain 20000.00
Munavvar 50000.00
Munavvar 50000.00
删除重复记录后 table应该包含这样的数据:
name salary
-----------------
Husain 20000.00
Munavvar 50000.00
答案 0 :(得分:3)
如果必须删除保留一行此类行的重复行,则可以在SQL中使用ROW_NUMBER()函数。删除行号>的所有行1.假设你知道ROW_NUMBER()和PARTITION是如何工作的。如果没有,你可以在msdn上获得更多相关信息。
DELETE A
FROM
(
SELECT name,salary, ROW_NUMBER() OVER (PARTITION BY name,salary ORDER BY name) AS rn
FROM Tab
) A
WHERE A.rn > 1
只是对@TimSchmelter的回复进行了提醒,它将删除所有重复项的存在。请注意区别,您可以根据自己的要求使用。
答案 1 :(得分:2)
使用子查询和GROUP BY HAVING COUNT(*) > 1
。
假设您要根据两列col1
和col2
找到重复项:
查询列出所有重复项:
SELECT t.*
FROM dbo.TableName t
INNER JOIN
(
SELECT [col1], [col2], Cnt = COUNT(*)
FROM dbo.TableName t
GROUP BY [col1], [col2]
HAVING COUNT(*) > 1
) Duplicates
ON t.[col1] = Duplicates.[col1] AND t.[col2] = Duplicates.[col2]
删除它们:
DELETE dbo.TableName
FROM dbo.TableName t
INNER JOIN
(
SELECT [col1], [col2], Cnt = COUNT(*)
FROM dbo.TableName t
GROUP BY [col1], [col2]
HAVING COUNT(*) > 1
) Duplicates
ON t.[col1] = Duplicates.[col1] AND t.[col2] = Duplicates.[col2]
答案 2 :(得分:0)
答案 3 :(得分:0)
select * from DuplicateRcordTable
WITH CTE
AS
(
SELECT *,
ROW_NUMBER() OVER(PARTITION BY Col3 ORDER BY Col3) AS DuplicateCount
FROM DuplicateRcordTable
)
DELETE
FROM CTE
WHERE DuplicateCount > 1
select * from DuplicateRcordTable2
答案 4 :(得分:0)
Select * into #temp
from Emp_Details
group by Name, Salary
having count(*) =1
现在,截断原始表
Truncate table Emp_Details
同样,将记录从临时表插入Emp_Details
insert Emp_Details (Name, Salary, Address)
Select Name, Age, Address from #temp
答案 5 :(得分:-1)
公用表表达式(CTE)的最常见用法是从没有主键的表中删除重复记录
WITH a as
(
SELECT A,ROW_NUMBER() OVER(PARTITION by A, B ORDER BY A)
AS duplicateRecCount dbo.A
)
--Now Delete Duplicate Records
DELETE FROM A
WHERE duplicateRecCount > 1 [enter image description here][1]
答案 6 :(得分:-1)
我们还可以使用光标或使用其他lopping语句从表中删除重复记录。以下代码spinets使用Cursor删除重复记录
DECLARE @A nvarchar(50), @B nvarchar(50) , @C nvarchar(50), @TotalDuplicate INT ;
DECLARE a_cursor CURSOR FOR
SELECT A, B ,C ,COUNT(1)-1 AS TotalDuplicate
FROM A
GROUP BY A, B ,C
HAVING COUNT(1)>1
OPEN a_cursor
FETCH NEXT FROM a_cursor INTO @A, @B,@C,@TotalDuplicate
WHILE @@FETCH_STATUS = 0
BEGIN
DELETE TOP (@TotalDuplicate) FROM A WHERE A=@A AND B=@B AND C=@C
FETCH NEXT FROM a_cursor INTO @A, @B,@C,@TotalDuplicate
END
CLOSE a_cursor;
DEALLOCATE a_cursor;