[转载]SQL Server 2005 中的Row_Number()函数 – 挖土. – 博客园.
我们知道,SQL Server 2005和SQL Server 2000 相比较,SQL Server 2005有很多新特性。这篇文章我们要讨论其中的一个新函数Row_Number()。数据库管理员和开发者已经期待这个函数很久了,现在终于等到了!
通常,开发者和管理员在一个查询里,用临时表和列相关的子查询来计算产生行号。现在SQL Server 2005提供了一个函数,代替所有多余的代码来产生行号。
我们假设有一个资料库[EMPLOYEETEST],资料库中有一个表[EMPLOYEE],你可以用下面的脚本来产生资料库,表和对应的数据。
<span class= "pln" >USE </span><span class= "pun" >[</span><span class= "pln" >MASTER</span><span class= "pun" >]</span><span class= "pln" > GO IF EXISTS </span><span class= "pun" >(</span><span class= "pln" > SELECT NAME FROM SYS</span><span class= "pun" >.</span><span class= "pln" >DATABASES WHERE NAME </span><span class= "pun" >=</span><span class= "pln" > N</span><span class= "str" > 'EMPLOYEE TEST' </span><span class= "pun" >)</span><span class= "pln" > DROP DATABASE </span><span class= "pun" >[</span><span class= "pln" >EMPLOYEE TEST</span><span class= "pun" >]</span><span class= "pln" > GO CREATE DATABASE </span><span class= "pun" >[</span><span class= "pln" >EMPLOYEE TEST</span><span class= "pun" >]</span><span class= "pln" > GO USE </span><span class= "pun" >[</span><span class= "pln" >EMPLOYEE TEST</span><span class= "pun" >]</span><span class= "pln" > GO IF EXISTS SELECT </span><span class= "pun" >*</span><span class= "pln" > FROM SYS</span><span class= "pun" >.</span><span class= "pln" >OBJECTS HERE OBJECT_ID </span><span class= "pun" >=</span><span class= "pln" > OBJECT_ID</span><span class= "pun" >(</span><span class= "pln" >N</span><span class= "str" > '[DBO].[EMPLOYEE]' </span><span class= "pun" >)</span><span class= "pln" > AND TYPE IN </span><span class= "pun" >(</span><span class= "pln" >N</span><span class= "str" > 'U' </span><span class= "pun" >))</span><span class= "pln" > DROP TABLE </span><span class= "pun" >[</span><span class= "pln" >DBO</span><span class= "pun" >].[</span><span class= "pln" >EMPLOYEE</span><span class= "pun" >]</span><span class= "pln" > GO CREATE TABLE EMPLOYEE </span><span class= "pun" >(</span><span class= "pln" >EMPID INT </span><span class= "pun" >,</span><span class= "pln" > FNAME VARCHAR </span><span class= "pun" >(</span><span class= "lit" >50</span><span class= "pun" >),</span><span class= "pln" >LNAME VARCHAR </span><span class= "pun" >(</span><span class= "lit" >50</span><span class= "pun" >))</span><span class= "pln" > GO INSERT INTO EMPLOYEE </span><span class= "pun" >(</span><span class= "pln" >EMPID</span><span class= "pun" >,</span><span class= "pln" > FNAME</span><span class= "pun" >,</span><span class= "pln" > LNAME</span><span class= "pun" >)</span><span class= "pln" > VALUES </span><span class= "pun" >(</span><span class= "lit" >2021110</span><span class= "pun" >,</span><span class= "pln" > </span><span class= "str" > 'MICHAEL' </span><span class= "pun" >,</span><span class= "pln" > </span><span class= "str" > 'POLAND' </span><span class= "pun" >)</span><span class= "pln" > INSERT INTO EMPLOYEE </span><span class= "pun" >(</span><span class= "pln" >EMPID</span><span class= "pun" >,</span><span class= "pln" > FNAME</span><span class= "pun" >,</span><span class= "pln" > LNAME</span><span class= "pun" >)</span><span class= "pln" > VALUES </span><span class= "pun" >(</span><span class= "lit" >2021110</span><span class= "pun" >,</span><span class= "pln" > </span><span class= "str" > 'MICHAEL' </span><span class= "pun" >,</span><span class= "pln" > </span><span class= "str" > 'POLAND' </span><span class= "pun" >)</span><span class= "pln" > INSERT INTO EMPLOYEE </span><span class= "pun" >(</span><span class= "pln" >EMPID</span><span class= "pun" >,</span><span class= "pln" > FNAME</span><span class= "pun" >,</span><span class= "pln" > LNAME</span><span class= "pun" >)</span><span class= "pln" > VALUES </span><span class= "pun" >(</span><span class= "lit" >2021115</span><span class= "pun" >,</span><span class= "pln" > </span><span class= "str" > 'JIM' </span><span class= "pun" >,</span><span class= "pln" > </span><span class= "str" > 'KENNEDY' </span><span class= "pun" >)</span><span class= "pln" > INSERT INTO EMPLOYEE </span><span class= "pun" >(</span><span class= "pln" >EMPID</span><span class= "pun" >,</span><span class= "pln" > FNAME</span><span class= "pun" >,</span><span class= "pln" > LNAME</span><span class= "pun" >)</span><span class= "pln" > VALUES </span><span class= "pun" >(</span><span class= "lit" >2121000</span><span class= "pun" >,</span><span class= "pln" > </span><span class= "str" > 'JAMES' </span><span class= "pun" >,</span><span class= "pln" > </span><span class= "str" > 'SMITH' </span><span class= "pun" >)</span><span class= "pln" > INSERT INTO EMPLOYEE </span><span class= "pun" >(</span><span class= "pln" >EMPID</span><span class= "pun" >,</span><span class= "pln" > FNAME</span><span class= "pun" >,</span><span class= "pln" > LNAME</span><span class= "pun" >)</span><span class= "pln" > VALUES </span><span class= "pun" >(</span><span class= "lit" >2011111</span><span class= "pun" >,</span><span class= "pln" > </span><span class= "str" > 'ADAM' </span><span class= "pun" >,</span><span class= "pln" > </span><span class= "str" > 'ACKERMAN' </span><span class= "pun" >)</span><span class= "pln" > INSERT INTO EMPLOYEE </span><span class= "pun" >(</span><span class= "pln" >EMPID</span><span class= "pun" >,</span><span class= "pln" > FNAME</span><span class= "pun" >,</span><span class= "pln" > LNAME</span><span class= "pun" >)</span><span class= "pln" > VALUES </span><span class= "pun" >(</span><span class= "lit" >3015670</span><span class= "pun" >,</span><span class= "pln" > </span><span class= "str" > 'MARTHA' </span><span class= "pun" >,</span><span class= "pln" > </span><span class= "str" > 'LEDERER' </span><span class= "pun" >)</span><span class= "pln" > INSERT INTO EMPLOYEE </span><span class= "pun" >(</span><span class= "pln" >EMPID</span><span class= "pun" >,</span><span class= "pln" > FNAME</span><span class= "pun" >,</span><span class= "pln" > LNAME</span><span class= "pun" >)</span><span class= "pln" > VALUES </span><span class= "pun" >(</span><span class= "lit" >1021710</span><span class= "pun" >,</span><span class= "pln" > </span><span class= "str" > 'MARIAH' </span><span class= "pun" >,</span><span class= "pln" > </span><span class= "str" > 'MANDEZ' </span><span class= "pun" >)</span><span class= "pln" > GO</span> |
SELECT EMPID, RNAME, LNAME FROM EMPLOYEE
这个查询的结果应该如图1.0
2021110 |
MICHAEL |
POLAND |
2021110 |
MICHAEL |
POLAND |
2021115 |
JIM |
KENNEDY |
2121000 |
JAMES |
SMITH |
2011111 |
ADAM |
ACKERMAN |
3015670 |
MARTHA |
LEDERER |
1021710 |
MARIAH |
MANDEZ |
图1.0
在SQL Server 2005,要根据这个表中的数据产生行号,我通常使用下面的查询。
SELECT ROWID=IDENTITY(int,1,1) , EMPID, FNAME, LNAME INTO EMPLOYEE2 FROM EMPLOYEE ORDER BY EMPID
这个查询创建了一个新的表,用identify函数来产生行号。我们用下面的查询来看看这个表的数据。
SELECT ROWID, EMPID, FNAME, LNAME FROM EMPLOYEE2
上面的查询结果如图1.1
1 |
1021710 |
MARIAH |
MANDEZ |
2 |
2011111 |
ADAM |
ACKERMAN |
3 |
2021110 |
MICHAEL |
POLAND |
4 |
2021110 |
MICHAEL |
POLAND |
5 |
2021115 |
JIM |
KENNEDY |
6 |
2121000 |
JAMES |
SMITH |
7 |
3015670 |
MARTHA |
LEDERER |
图1.1
这个查询结果很明显EMP=2021110的行是重复的数据。
要删除EMPID=2021110的重复数据,我们必须在EMPLOYEE2表中删除,不能直接在EMPLOYEE中删除。
SQL Server 2005提供了一个新的函数(Row_Number())来产生行号。我们可以使用这个新函数来删除原来表中的重复数据,只用通常的表达方式再加上Row_Number()函数。
让我们用Row_Number()函数根据EMPID来产生ROWID。
SELECT ROW_NUMBER() OVER (ORDER BY EMPID ASC) AS ROWID, * FROM EMPLOYEE
上面的查询结果如图1.2
1 |
1021710 |
MARIAH |
MANDEZ |
2 |
2011111 |
ADAM |
ACKERMAN |
3 |
2021110 |
MICHAEL |
POLAND |
4 |
2021110 |
MICHAEL |
POLAND |
5 |
2021115 |
JIM |
KENNEDY |
6 |
2121000 |
JAMES |
SMITH |
7 |
3015670 |
MARTHA |
LEDERER |
图1.2
在这个结果中,我们可以区别EMPID是2021110的重复数据。
我们可以用通用表查询表达式和Row_Numner()函数来选出重复的那行数据。
WITH [EMPLOYEE ORDERED BY ROWID] AS
(SELECT ROW_NUMBER() OVER (ORDER BY EMPID ASC) AS ROWID, * FROM EMPLOYEE)
SELECT * FROM [EMPLOYEE ORDERED BY ROWID] WHERE ROWID =4
上面的查询结果如图1.3
4 |
2021110 |
MICHAEL |
POLAND |
图1.3
这一行重复的数据可以用下面这个通用表和Row_Number()函数来删除。
WITH [EMPLOYEE ORDERED BY ROWID] AS
(SELECT ROW_NUMBER() OVER (ORDER BY EMPID ASC) AS ROWID, * FROM EMPLOYEE)
DELETE FROM [EMPLOYEE ORDERED BY ROWID] WHERE ROWID =4
删除以后,我们可以用下面的查询语句看一下结果。
SELECT * FROM EMPLOYEE
这个查询结果如图1.4
2021110 |
MICHAEL |
POLAND |
2021115 |
JIM |
KENNEDY |
2121000 |
JAMES |
SMITH |
2011111 |
ADAM |
ACKERMAN |
3015670 |
MARTHA |
LEDERER |
1021710 |
MARIAH |
MANDEZ |
图 1.4
这里我们可以看到,重复的数据已经被删除了。
总结
在这篇文章中,我们讨论了SQL Server 2005 的新特性Row_Number()函数,还有通常的表表达式,然后如何使用这两个来删除重复的行。
______________________________________________
原文:http://www.databasejournal.com/features/mssql/article.php/3577481