给定一个示例表'Users',它有一个名为'UserID'的int列(以及一些任意数量的其他列),选择UserID多次出现的所有行的最佳方法是什么?
到目前为止,我已经提出了
select * from Users where UserID in
(select UserID from Users group by UserID having COUNT(UserID) > 1)
这似乎是一种非常有效的方法,但有更好的方法吗?
答案 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