【发布时间】:2013-11-16 02:00:51
【问题描述】:
我正在尝试识别重复记录,然后使用 PARTITION 和 RANK() n SQL Server 2008 删除其中一条重复记录。我删除重复记录的条件是它不应在另一个表中引用。
我有一个包含一些重复语言的语言表。员工表有员工和语言映射。如果该语言 ID 未映射到 Employee 表中,我必须删除其中一条重复记录。
CREATE TABLE MY_LANGUAGE (LANGUAGEID INT, LANGUAGENAME VARCHAR(20))
CREATE TABLE MY_EMPLOYEE (EMPID INT, NAME VARCHAR(20), LANGUAGEID INT)
INSERT INTO MY_LANGUAGE VALUES(1, 'ENGLISH')
INSERT INTO MY_LANGUAGE VALUES(2, 'FRENCH')
INSERT INTO MY_LANGUAGE VALUES(3, 'ITALIAN')
INSERT INTO MY_LANGUAGE VALUES(4, 'GERMAN')
INSERT INTO MY_LANGUAGE VALUES(5, 'ITALIAN')
INSERT INTO MY_LANGUAGE VALUES(6, 'GERMAN')
INSERT INTO MY_LANGUAGE VALUES(7, 'SPANISH')
INSERT INTO MY_EMPLOYEE VALUES (10, 'GLEN', 1)
INSERT INTO MY_EMPLOYEE VALUES (20, 'PETER', 2)
INSERT INTO MY_EMPLOYEE VALUES (30, 'MARIA', 3)
如果您看到,我有两种语言是重复的,其中一种正在被员工使用。我想删除语言 ID 4 和 5。
LANGUAGENAME LANGUAGEID EMPNAME
GERMAN 4
GERMAN 6
ITALIAN 3 MARIA
ITALIAN 5
我试图创建一个选择语句来返回我要删除的内容:
WITH CTE AS (
SELECT L.LANGUAGENAME, L.LANGUAGEID, RANK() OVER(PARTITION BY L.LANGUAGENAME ORDER BY L.LANGUAGEID) AS RANKING
FROM MY_LANGUAGE L
INNER JOIN (
SELECT LANGUAGENAME, COUNT(*) AS DUPECOUNT
FROM MY_LANGUAGE
GROUP BY LANGUAGENAME
HAVING COUNT(*) > 1
) LC ON L.LANGUAGENAME = LC.LANGUAGENAME
WHERE NOT EXISTS (SELECT 1 FROM MY_EMPLOYEE WHERE MY_EMPLOYEE.LANGUAGEID = L.LANGUAGEID))
SELECT * FROM CTE WHERE RANKING = 1
这会返回以下内容
LANGUAGENAME LANGUAGEID RANKING
GERMAN 4 1
ITALIAN 5 1
当我尝试删除时出现错误:
WITH CTE AS (
SELECT L.LANGUAGENAME, L.LANGUAGEID, RANK() OVER(PARTITION BY L.LANGUAGENAME ORDER BY L.LANGUAGEID) AS RANKING
FROM MY_LANGUAGE L
INNER JOIN (
SELECT LANGUAGENAME, COUNT(*) AS DUPECOUNT
FROM MY_LANGUAGE
GROUP BY LANGUAGENAME
HAVING COUNT(*) > 1
) LC ON L.LANGUAGENAME = LC.LANGUAGENAME
WHERE NOT EXISTS (SELECT 1 FROM MY_EMPLOYEE WHERE MY_EMPLOYEE.LANGUAGEID = L.LANGUAGEID))
DELETE FROM CTE WHERE RANKING = 1
我得到的错误是:
消息 4405,第 16 级,状态 1,第 1 行
视图或函数“CTE”不可更新,因为修改会影响多个基表。
任何如何解决这个问题的想法,或者可能是它可以被简化。感谢@Szymon 展示了一个临时表解决方案,但我希望得到一个没有临时表的解决方案(如果可能的话)。
【问题讨论】:
标签: sql-server duplicate-removal