-
--处理表重复记录(查询和删除)
-
/******************************************************************************************************************************************************
-
1、Num、Name相同的重复值记录,没有大小关系只保留一条
-
2、Name相同,ID有大小关系时,保留大或小其中一个记录
-
-
-
日期:2008.06.06
-
******************************************************************************************************************************************************/
-
-
--1、用于查询重复处理记录(如果列没有大小关系时2000用生成自增列和临时表处理,SQL2005用row_number函数处理)
-
-
--> --> (Roy)生成測試數據
-
-
IF not
OBJECT_ID
(
'Tempdb..#T'
)
IS null
-
DROP
TABLE #T
-
Go
-
CREATE
TABLE #T
([ID
]
INT,
[Name
]
NVARCHAR
(
1
),
[Memo
]
NVARCHAR
(
2
))
-
INSERT #T
-
SELECT
1,N
'A',N
'A1'
UNION all
-
SELECT
2,N
'A',N
'A2'
UNION all
-
SELECT
3,N
'A',N
'A3'
UNION all
-
SELECT
4,N
'B',N
'B1'
UNION all
-
SELECT
5,N
'B',N
'B2'
-
Go
-
-
-
--I、Name相同ID最小的记录(推荐用1,2,3),方法3在SQl05时,效率高于1、2
-
方法
1:
-
SELECT
*
FROM #T a
WHERE not exists
(
SELECT
1
FROM #T
WHERE Name
=a.
Name and ID
<a.
ID
)
-
-
方法
2:
-
SELECT a.
*
FROM #T a join
(
SELECT
MIN
(ID
)ID,Name
FROM #T
GROUP
BY Name
) b
ON a.
Name
=b.
Name and a.
ID
=b.
ID
-
-
方法
3:
-
SELECT
*
FROM #T a
WHERE ID
=(
SELECT
MIN
(ID
)
FROM #T
WHERE Name
=a.
Name
)
-
-
方法
4:
-
SELECT a.
*
FROM #T a join #T b
ON a.
Name
=b.
Name and a.
ID
>=b.
ID
GROUP
BY a.
ID,a.
Name,a.
Memo
HAVING
COUNT
(
1
)=
1
-
-
方法
5:
-
SELECT
*
FROM #T a
GROUP
BY ID,Name,Memo
HAVING ID
=(
SELECT
MIN
(ID
)
FROM #T
WHERE Name
=a.
Name
)
-
-
方法
6:
-
SELECT
*
FROM #T a
WHERE
(
SELECT
COUNT
(
1
)
FROM #T
WHERE Name
=a.
Name and ID
<a.
ID
)=
0
-
-
方法
7:
-
SELECT
*
FROM #T a
WHERE ID
=(
SELECT
TOP
1 ID
FROM #T
WHERE Name
=a.
name
ORDER
BY ID
)
-
-
方法
8:
-
SELECT
*
FROM #T a
WHERE ID
!>all
(
SELECT ID
FROM #T
WHERE Name
=a.
Name
)
-
-
方法
9
(注:ID为唯一时可用
):
-
SELECT
*
FROM #T a
WHERE ID in
(
SELECT
MIN
(ID
)
FROM #T
GROUP
BY Name
)
-
-
--SQL2005:
-
-
方法
10:
-
SELECT ID,Name,Memo
FROM
(
SELECT
*,
MIN
(ID
)
OVER
(partition
BY Name
)
AS MinID
FROM #T a
)T
WHERE ID
=MinID
-
-
方法
11:
-
-
SELECT ID,Name,Memo
FROM
(
SELECT
*,row_number
()
OVER
(partition
BY Name
ORDER
BY ID
)
AS MinID
FROM #T a
)T
WHERE MinID
=
1
-
-
生成结果:
-
/*
-
ID Name Memo
-
----------- ---- ----
-
1 A A1
-
4 B B1
-
-
(2 行受影响)
-
*/
-
-
-
--II、Name相同ID最大的记录,与min相反:
-
方法
1:
-
SELECT
*
FROM #T a
WHERE not exists
(
SELECT
1
FROM #T
WHERE Name
=a.
Name and ID
>a.
ID
)
-
-
方法
2:
-
SELECT a.
*
FROM #T a join
(
SELECT
MAX
(ID
)ID,Name
FROM #T
GROUP
BY Name
) b
ON a.
Name
=b.
Name and a.
ID
=b.
ID
ORDER
BY ID
-
-
方法
3:
-
SELECT
*
FROM #T a
WHERE ID
=(
SELECT
MAX
(ID
)
FROM #T
WHERE Name
=a.
Name
)
ORDER
BY ID
-
-
方法
4:
-
SELECT a.
*
FROM #T a join #T b
ON a.
Name
=b.
Name and a.
ID
<=b.
ID
GROUP
BY a.
ID,a.
Name,a.
Memo
HAVING
COUNT
(
1
)=
1
-
-
方法
5:
-
SELECT
*
FROM #T a
GROUP
BY ID,Name,Memo
HAVING ID
=(
SELECT
MAX
(ID
)
FROM #T
WHERE Name
=a.
Name
)
-
-
方法
6:
-
SELECT
*
FROM #T a
WHERE
(
SELECT
COUNT
(
1
)
FROM #T
WHERE Name
=a.
Name and ID
>a.
ID
)=
0
-
-
方法
7:
-
SELECT
*
FROM #T a
WHERE ID
=(
SELECT
TOP
1 ID
FROM #T
WHERE Name
=a.
name
ORDER
BY ID
DESC
)
-
-
方法
8:
-
SELECT
*
FROM #T a
WHERE ID
!<all
(
SELECT ID
FROM #T
WHERE Name
=a.
Name
)
-
-
方法
9
(注:ID为唯一时可用
):
-
SELECT
*
FROM #T a
WHERE ID in
(
SELECT
MAX
(ID
)
FROM #T
GROUP
BY Name
)
-
-
--SQL2005:
-
-
方法
10:
-
SELECT ID,Name,Memo
FROM
(
SELECT
*,
MAX
(ID
)
OVER
(partition
BY Name
)
AS MinID
FROM #T a
)T
WHERE ID
=MinID
-
-
方法
11:
-
SELECT ID,Name,Memo
FROM
(
SELECT
*,row_number
()
OVER
(partition
BY Name
ORDER
BY ID
DESC
)
AS MinID
FROM #T a
)T
WHERE MinID
=
1
-
-
生成结果
2:
-
/*
-
ID Name Memo
-
----------- ---- ----
-
3 A A3
-
5 B B2
-
-
(2 行受影响)
-
*/
-
-
-
-
--2、删除重复记录有大小关系时,保留大或小其中一个记录
-
-
-
--> --> (Roy)生成測試數據
-
-
IF not
OBJECT_ID
(
'Tempdb..#T'
)
IS null
-
DROP
TABLE #T
-
Go
-
CREATE
TABLE #T
([ID
]
INT,
[Name
]
NVARCHAR
(
1
),
[Memo
]
NVARCHAR
(
2
))
-
INSERT #T
-
SELECT
1,N
'A',N
'A1'
UNION all
-
SELECT
2,N
'A',N
'A2'
UNION all
-
SELECT
3,N
'A',N
'A3'
UNION all
-
SELECT
4,N
'B',N
'B1'
UNION all
-
SELECT
5,N
'B',N
'B2'
-
Go
-
-
--I、Name相同ID最小的记录(推荐用1,2,3),保留最小一条
-
方法
1:
-
DELETE a
FROM #T a
WHERE exists
(
SELECT
1
FROM #T
WHERE Name
=a.
Name and ID
<a.
ID
)
-
-
方法
2:
-
DELETE a
FROM #T a
LEFT join
(
SELECT
MIN
(ID
)ID,Name
FROM #T
GROUP
BY Name
) b
ON a.
Name
=b.
Name and a.
ID
=b.
ID
WHERE b.
Id
IS null
-
-
方法
3:
-
DELETE a
FROM #T a
WHERE ID not in
(
SELECT
MIN
(ID
)
FROM #T
WHERE Name
=a.
Name
)
-
-
方法
4
(注:ID为唯一时可用
):
-
DELETE a
FROM #T a
WHERE ID not in
(
SELECT
MIN
(ID
)
FROM #T
GROUP
BY Name
)
-
-
方法
5:
-
DELETE a
FROM #T a
WHERE
(
SELECT
COUNT
(
1
)
FROM #T
WHERE Name
=a.
Name and ID
<a.
ID
)>
0
-
-
方法
6:
-
DELETE a
FROM #T a
WHERE ID
<>(
SELECT
TOP
1 ID
FROM #T
WHERE Name
=a.
name
ORDER
BY ID
)
-
-
方法
7:
-
DELETE a
FROM #T a
WHERE ID
>any
(
SELECT ID
FROM #T
WHERE Name
=a.
Name
)
-
-
-
-
SELECT
*
FROM #T
-
-
生成结果:
-
/*
-
ID Name Memo
-
----------- ---- ----
-
1 A A1
-
4 B B1
-
-
(2 行受影响)
-
*/
-
-
-
--II、Name相同ID保留最大的一条记录:
-
-
方法
1:
-
DELETE a
FROM #T a
WHERE exists
(
SELECT
1
FROM #T
WHERE Name
=a.
Name and ID
>a.
ID
)
-
-
方法
2:
-
DELETE a
FROM #T a
LEFT join
(
SELECT
MAX
(ID
)ID,Name
FROM #T
GROUP
BY Name
) b
ON a.
Name
=b.
Name and a.
ID
=b.
ID
WHERE b.
Id
IS null
-
-
方法
3:
-
DELETE a
FROM #T a
WHERE ID not in
(
SELECT
MAX
(ID
)
FROM #T
WHERE Name
=a.
Name
)
-
-
方法
4
(注:ID为唯一时可用
):
-
DELETE a
FROM #T a
WHERE ID not in
(
SELECT
MAX
(ID
)
FROM #T
GROUP
BY Name
)
-
-
方法
5:
-
DELETE a
FROM #T a
WHERE
(
SELECT
COUNT
(
1
)
FROM #T
WHERE Name
=a.
Name and ID
>a.
ID
)>
0
-
-
方法
6:
-
DELETE a
FROM #T a
WHERE ID
<>(
SELECT
TOP
1 ID
FROM #T
WHERE Name
=a.
name
ORDER
BY ID
DESC
)
-
-
方法
7:
-
DELETE a
FROM #T a
WHERE ID
<any
(
SELECT ID
FROM #T
WHERE Name
=a.
Name
)
-
-
-
SELECT
*
FROM #T
-
/*
-
ID Name Memo
-
----------- ---- ----
-
3 A A3
-
5 B B2
-
-
(2 行受影响)
-
*/
-
-
-
-
-
-
--3、删除重复记录没有大小关系时,处理重复值
-
-
-
--> --> (Roy)生成測試數據
-
-
IF not
OBJECT_ID
(
'Tempdb..#T'
)
IS null
-
DROP
TABLE #T
-
Go
-
CREATE
TABLE #T
([Num
]
INT,
[Name
]
NVARCHAR
(
1
))
-
INSERT #T
-
SELECT
1,N
'A'
UNION all
-
SELECT
1,N
'A'
UNION all
-
SELECT
1,N
'A'
UNION all
-
SELECT
2,N
'B'
UNION all
-
SELECT
2,N
'B'
-
Go
-
-
方法
1:
-
IF
OBJECT_ID
(
'Tempdb..#'
)
IS not null
-
DROP
TABLE #
-
SELECT
DISTINCT
*
INTO #
FROM #T
--排除重复记录结果集生成临时表#
-
-
TRUNCATE
TABLE #T
--清空表
-
-
INSERT #T
SELECT
*
FROM #
--把临时表#插入到表#T中
-
-
--查看结果
-
SELECT
*
FROM #T
-
-
/*
-
Num Name
-
----------- ----
-
1 A
-
2 B
-
-
(2 行受影响)
-
*/
-
-
--重新执行测试数据后用方法2
-
方法
2:
-
-
ALTER
TABLE #T
ADD ID
INT
IDENTITY
--新增标识列
-
go
-
DELETE a
FROM #T a
WHERE exists
(
SELECT
1
FROM #T
WHERE Num
=a.
Num and Name
=a.
Name and ID
>a.
ID
)
--只保留一条记录
-
go
-
ALTER
TABLE #T
DROP
COLUMN ID
--删除标识列
-
-
--查看结果
-
SELECT
*
FROM #T
-
-
/*
-
Num Name
-
----------- ----
-
1 A
-
2 B
-
-
(2 行受影响)
-
-
*/
-
-
--重新执行测试数据后用方法3
-
方法
3:
-
DECLARE Roy_Cursor
CURSOR
LOCAL
FOR
-
SELECT
COUNT
(
1
)
-1,Num,Name
FROM #T
GROUP
BY Num,Name
HAVING
COUNT
(
1
)>
1
-
DECLARE @con
INT,@Num
INT,@Name
NVARCHAR
(
1
)
-
OPEN Roy_Cursor
-
FETCH
NEXT
FROM Roy_Cursor
INTO @con,@Num,@Name
-
WHILE
@@FETCH_STATUS
=
0
-
BEGIN
-
SET rowcount @con;
-
DELETE #T
WHERE Num
=@Num and Name
=@Name
-
SET rowcount
0;
-
FETCH
NEXT
FROM Roy_Cursor
INTO @con,@Num,@Name
-
END
-
CLOSE Roy_Cursor
-
DEALLOCATE Roy_Cursor
-
-
--查看结果
-
SELECT
*
FROM #T
-
/*
-
Num Name
-
----------- ----
-
1 A
-
2 B
-
-
(2 行受影响)
-
*/