求SQL话语构造,关于数据库中的重复数据的
求SQL语句构造,关于数据库中的重复数据的
现有一个书目数据表,有大概几万条数据,字段如下:
ID 书名 责任者 出版社 出版年 ISBN 分类号 简介
因为有重复,所以要找出重复的记录并删除。系统要求比如两条数据如果 书名、责任者、ISBN号这三个字段一样的话,就算重复,只保留一条记录。
其中有个难点是比如责任者是“张三”,“张三著”、“张三编”也认为和“张三”是一样的。
求大侠帮忙构造SQL语句,感激不尽!
------解决方案--------------------
耐心看看吧, 没有用循环, 而且有完整的测试数据和测试表, 复制过去粘贴 F5 即可看效果了!
睡觉了,
现有一个书目数据表,有大概几万条数据,字段如下:
ID 书名 责任者 出版社 出版年 ISBN 分类号 简介
因为有重复,所以要找出重复的记录并删除。系统要求比如两条数据如果 书名、责任者、ISBN号这三个字段一样的话,就算重复,只保留一条记录。
其中有个难点是比如责任者是“张三”,“张三著”、“张三编”也认为和“张三”是一样的。
求大侠帮忙构造SQL语句,感激不尽!
------解决方案--------------------
IF OBJECT_ID('testBooks') IS NOT NULL
BEGIN
DROP TABLE testBooks
END
GO
CREATE TABLE testBooks
(
ID INT,
bookName nvarchar(maX), -- 重复项
Author nvarchar(maX), -- 重复项
出版社 nvarchar(max),
出版年 int,
ISBN nvarchar(maX), -- 重复项
分类号 nvarchar(max),
简介 nvarchar(max),
)
GO
INSERT INTO testBooks( ID, bookName,Author,出版社,出版年,ISBN )
SELECT 1,'红楼梦','张三','小鸡出版社',2012,'1234567' union all
SELECT 2,'红楼梦','张三痪','小鸡出版社',2012,'1234567' union all
SELECT 3,'红楼梦','张三著','小鸡出版社',2012,'1234567' union all
SELECT 4,'红楼梦','张三编','小鸡出版社',2012,'1234567' union all
SELECT 5,'红楼梦','张三','小鸡出版社',2012,'1234567' union all
SELECT 6,'梦之声','李四','小鸡出版社',2012,'123456' union all
SELECT 7,'梦之声','李四著','小鸡出版社',2012,'123456' union all
SELECT 8,'梦之声','王五','小鸡出版社',2012,'123456'
--以上数据, 应该删除3,4,5,7, 并保留 1, 2, 6, 8 三条才是对的
--定义要删除的记录的 ID
DECLARE @ID_table TABLE (Id INT);
--得到重复的记录
;WITH t1 AS (
SELECT * FROM testBooks a WHERE EXISTS
(
SELECT 1 FROM testBooks b WHERE a.id !=b.ID AND a.ISBN=b.ISBN AND a.bookName=b.bookName AND
(a.Author=b.Author OR a.Author LIKE '%'+b.Author+'著' OR a.Author LIKE '%'+b.Author+'编'
OR b.Author LIKE '%'+a.Author+'著' OR b.Author LIKE '%'+a.Author+'编'
)
)
),
--将重复的记录分离出对应的 ISBN
temp AS (
SELECT a.ISBN FROM testBooks a WHERE EXISTS
(
SELECT 1 FROM testBooks b WHERE a.id !=b.ID AND a.ISBN=b.ISBN AND a.bookName=b.bookName AND
(a.Author=b.Author OR a.Author LIKE '%'+b.Author+'著' OR a.Author LIKE '%'+b.Author+'编'
OR b.Author LIKE '%'+a.Author+'著' OR b.Author LIKE '%'+a.Author+'编'
)
)
GROUP BY a.ISBN
)
INSERT INTO @ID_table
SELECT ID FROM testBooks c WHERE c.ISBN IN (
SELECT c.ISBN FROM temp
) AND c.ID NOT IN (SELECT MIN(ID) FROM testBooks tb WHERE tb.ISBN =c.ISBN)
AND c.ID IN (SELECT id FROM t1)
ORDER BY c.ID
--查看需要删除的记录
SELECT * FROM testBooks a WHERE a.ID IN (SELECT ID FROM @ID_table)
/*
3 红楼梦 张三著 小鸡出版社 2012 1234567 NULL NULL
4 红楼梦 张三编 小鸡出版社 2012 1234567 NULL NULL
5 红楼梦 张三 小鸡出版社 2012 1234567 NULL NULL
7 梦之声 李四著 小鸡出版社 2012 123456 NULL NULL
* */
--删除记录
DELETE FROM testBooks WHERE id IN (SELECT ID FROM @ID_table)
--再查看原来的表, 终于干净了……
SELECT * FROM testBooks a
/*
1 红楼梦 张三 小鸡出版社 2012 1234567 NULL NULL
2 红楼梦 张三痪 小鸡出版社 2012 1234567 NULL NULL
6 梦之声 李四 小鸡出版社 2012 123456 NULL NULL
8 梦之声 王五 小鸡出版社 2012 123456 NULL NULL
* */
--删除测试表
DROP TABLE testBooks
耐心看看吧, 没有用循环, 而且有完整的测试数据和测试表, 复制过去粘贴 F5 即可看效果了!
睡觉了,