在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
三種解決方案給出相同的計劃。
不知道什麼意思?你有數百萬用戶還是什麼?我認爲你的查詢很好,如果您有數以百萬計的行,那麼當然UserID必須爲此類查詢編制索引。 – Arvo 2011-04-06 13:50:48
我直覺地覺得必須有一些方法來做到這一點,而不使用子查詢。當然,我可能完全錯誤。 – John 2011-04-06 13:54:03
更重要的是:爲什麼userID'ever'會在Users表中多次出現? – 2011-04-06 14:01:01