Tsql,返回具有相同列值的行

时间:2011-04-06 13:47:30

标签: tsql

给定一个示例表'Users',它有一个名为'UserID'的int列(以及一些任意数量的其他列),选择UserID多次出现的所有行的最佳方法是什么?

到目前为止,我已经提出了

select * from Users where UserID in 
(select UserID from Users group by UserID having COUNT(UserID) > 1)

这似乎是一种非常有效的方法,但有更好的方法吗?

2 个答案:

答案 0 :(得分:2)

在SQL Server 2005+中,您可以使用此方法:

;WITH UsersNumbered AS (
  SELECT
    UserID,
    rownum = ROW_NUMBER() OVER (PARTITION BY UserID ORDER BY UserID)
  FROM Users
)
SELECT u.*
FROM Users u
  INNER JOIN UsersNumbered n ON u.UserID = n.UserID AND n.rownum = 2

如果UserID上存在非聚集索引,则会产生比您的方法稍差的执行计划。为了使它更好(实际上,与你的相同),你需要使用...一个子查询,但看起来反直觉:

;WITH UsersNumbered AS (
  SELECT
    UserID,
    rownum = ROW_NUMBER() OVER (PARTITION BY UserID ORDER BY UserID)
  FROM Users
)
SELECT u.*
FROM Users u
WHERE EXISTS (
  SELECT *
  FROM UsersNumbered n
  WHERE u.UserID = n.UserID AND n.rownum = 2
);

如果UserID上有聚集索引,则所有三个解决方案都会给出相同的计划。

答案 1 :(得分:0)

这可以做同样的事情,但评估性能,它可能会更快/更有效。当然,此UserID列应该有一个索引。

select u.*
from Users u
join (select UserID,count(UserID) as CUserID from Users group by UserID) u1 on u1.UserID = u.UserID
where CUserID > 1