请清楚说明CTE查询?

时间:2018-09-21 06:01:14

标签: sql-server-2008

我看到了

WITH tblTemp as
(
   SELECT ROW_NUMBER() Over(PARTITION BY Name,Department ORDER BY Name) As RowNumber, * 
   FROM <table_name>
)
DELETE FROM tblTemp where RowNumber > 1

此查询用于删除重复的行,但我无法理解该查询。你能解释清楚吗?

2 个答案:

答案 0 :(得分:0)

common table expression正在查找重复的行,然后,如果存在重复,则随后的删除查询将删除除一行以外的所有行。

SELECT
   ROW_NUMBER() Over(PARTITION BY Name,Department ORDER BY Name) As RowNumber
   ,* 
FROM <table_name>

over()子句中,partitionorder by定义了从1开始的编号,然后在每个partition中,每个额外的行都获得了更大的行号。因此,当[RowNumber] = 1时,您具有一组唯一的名称和部门行。

请参阅:Over()row_number()

Demonstration

CREATE TABLE mytable(
   name       VARCHAR(6) NOT NULL
  ,department VARCHAR(11) NOT NULL
);
INSERT INTO mytable(name,department) VALUES ('fred','sales');
INSERT INTO mytable(name,department) VALUES ('fred','sales');
INSERT INTO mytable(name,department) VALUES ('barney','admin');
INSERT INTO mytable(name,department) VALUES ('barney','admin');
INSERT INTO mytable(name,department) VALUES ('wilma','engineering');



WITH tblTemp as
(
   SELECT ROW_NUMBER() Over(PARTITION BY Name,Department ORDER BY Name) As RowNumber, * 
   FROM mytable
)
DELETE FROM tblTemp where RowNumber > 1
;

select
*
from mytable
;

+---+--------+-------------+
|   |  name  | department  |
+---+--------+-------------+
| 1 | fred   | sales       |
| 2 | barney | admin       |
| 3 | wilma  | engineering |
+---+--------+-------------+

答案 1 :(得分:0)

对您来说最具启发性的事情是从CTE中进行选择:

SELECT *
FROM tblTemp
ORDER BY Department, Name;

在我的头顶上,您可能会看到如下所示的结果集:

Name          | Department | RowNumber
Jon Skeet     | Software   | 1
Gordon Linoff | Database   | 1
Gordon Linoff | Database   | 2

(Gordon Linoff, Database)记录重复出现,因此第二条记录中的行号值大于1。您的删除逻辑将删除此重复项,但不会影响(Jon Skeet, Software)记录,没有重复。