Извлечь строку, которая имеет значение Max для столбца в SQL Server - PullRequest
6 голосов
/ 20 января 2010

Я нашел вопрос, который был очень похож на этот, но с использованием функций, которые кажутся исключительно Oracle. Я ищу это в SQL Server.

У меня есть такая таблица:

MyTable
--------------------
MyTableID  INT  PK
UserID     INT
Counter    INT

Каждый пользователь может иметь несколько строк, с различными значениями для Counter в каждой строке. Мне нужно найти строки с самым высоким значением Counter для каждого пользователя.

Как я могу сделать это в SQL Server 2005?

Лучшее, что я могу придумать, - это запрос, который возвращает MAX(Counter) для каждого UserID, но мне нужна вся строка, потому что другие данные в этой таблице не показаны в моем определении таблицы для простоты.

РЕДАКТИРОВАТЬ: Из некоторых ответов в этом посте мне стало известно, что я забыл важную деталь. Можно иметь 2+ строки, в которых идентификатор пользователя может иметь одинаковое значение счетчика MAX. Пример ниже обновлен для того, чтобы быть ожидаемыми данными / выводом.

С этими данными:

MyTableID   UserID   Counter
---------   -------  --------
1           1         4
2           1         7
3           4         3
4           11        9
5           11        3
6           4         6
...
9           11        9

Я хочу, чтобы эти результаты были получены для дублированных значений MAX, выберите первое вхождение в любом порядке, в котором их выбирает SQL-сервер. Какие строки возвращаются, не важно в этом случае, если пары UserID / Counter различны:

MyTableID   UserID    Counter
---------   -------   --------
2           1         7
4           11        9
6           4         6

Ответы [ 5 ]

9 голосов
/ 20 января 2010

Мне нравится использовать Common Table Expression для этого случая с подходящей функцией ROW_NUMBER ():

WITH MaxPerUser AS
(
  SELECT 
    MyTableID, UserID, Counter,
    ROW_NUMBER() OVER(PARTITION BY userid ORDER BY Counter DESC) AS 'RowNumber'
  FROM dbo.MyTable
)
SELECT MyTableID, UserID, Counter 
FROM MaxPerUser
WHERE RowNumber = 1

, которая разбивает данные на UserID, упорядочивает их по Counter (по убыванию) длякаждого пользователя, а затем помечает каждую строку, начиная с 1 для каждого пользователя.Выберите только те строки с 1 для rownumber, и у вас есть ваш макс.значений на пользователя.

Это так просто :-) И я получаю результаты примерно так:

MyTableID   UserID  Counter  
   2           1        7   
   6           4        6
   4          11        9

Только одна запись на пользователя, независимо от того, сколько строк на пользователя имеетто же самое максимальное значение.

2 голосов
/ 05 мая 2012

Я думаю, что это поможет вам.

SELECT distinct(a.userid), MAX(a.counterid) as counterid 
FROM    mytable a INNER JOIN mytable b ON a.mytableid = b.mytableid 
GROUP BY a.userid
0 голосов
/ 20 января 2010

Попробуйте ... Я уверен, что это единственный способ убедиться, что вы получаете по одной строке на пользователя.

SELECT MT.* 
FROM    MyTable MT
    INNER JOIN (
        SELECT  MAX(MID.MyTableId) AS MaxMyTableId,
            MID.UserId
        FROM    MyTable MID
            INNER JOIN (
                SELECT  MAX(Counter) AS MaxCounter, UserId
                FROM    MyTable
                GROUP BY UserId
            ) AS MC
                ON (MID.UserId = MC.UserId
                    AND MID.Counter = MC.MaxCounter)
        GROUP BY MID.UserId
    ) AS MID
        ON (MID.UserId = MC.UserId
            AND MID.MyTableId = MC.MaxMyTableId)
0 голосов
/ 20 января 2010
select m.* 
from MyTable m
inner join (
    select UserID, max(Counter) as MaxCounter
    from MyTable
    group by UserID
) mm on m.UserID = mm.UserID and m.Counter = mm.MaxCounter
0 голосов
/ 20 января 2010

Есть несколько способов сделать это, посмотрите на это Включая связанные значения агрегированного столбца Показаны несколько методов, включая различия в производительности

Вот один пример

select t1.*
from(
select UserID, max(counter) as MaxCount
from MyTable
group by UserID) t2
join MyTable t1 on t2.UserID =t1.UserID
and t1.counter = t2.counter
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...