Tsql, возвращая строки с одинаковыми значениями столбца - PullRequest
1 голос
/ 06 апреля 2011

Для примера таблицы «Users», в которой есть столбец int с именем «UserID» (и некоторое произвольное количество других столбцов), каков наилучший способ выбрать все строки, из которых UserID появляется более одного раза?

До сих пор я придумал

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

Это кажется довольно неэффективным способом сделать это, хотя, есть ли лучший способ?

Ответы [ 2 ]

2 голосов
/ 06 апреля 2011

В 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 все три решения дают один и тот же план.

0 голосов
/ 06 апреля 2011

Это будет делать то же самое, но оценивать производительность и, скорее всего, будет быстрее / эффективнее. Конечно, в этом столбце 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...