Tsql - получить всю информацию о строке с max и group by - PullRequest
4 голосов
/ 14 августа 2010

У меня есть таблица со следующими столбцами:

PK1   PK2   ID   DATE    Value  flag

Я делаю расчет, который включает в себя получение максимального значения для каждого идентификатора.

  select id,
         max(value) 
    from table 
group by id

Я хочу отметить флаг в строках, которые я использую.Если id и max (значение) соответствуют нескольким строкам, отметьте ту, которая имеет максимальную дату.Если они имеют одинаковый идентификатор, max (значение) и max (дата) помечают ровно одну из этих строк (не важно, какая на данный момент)

Есть идеи?

Спасибо!

Ответы [ 3 ]

10 голосов
/ 14 августа 2010

Для SQL2005 + может быть что-то вроде этого.(Предполагая, что «Пометить» означает обновить столбец флага)

WITH cte AS
(
SELECT PK1, PK2, ID, DATE, Value, flag,
ROW_NUMBER() OVER (PARTITION BY id ORDER BY value desc, date desc) AS RN
FROM table 
)
UPDATE cte
SET flag=CASE WHEN RN=1 THEN 1 ELSE 0 END
5 голосов
/ 14 августа 2010

В SQL Server 2005 или более поздней версии вы можете выполнять следующие действия:

SELECT x.*
FROM (
 SELECT *,
        ROW_NUMBER() OVER (PARTITION BY id ORDER BY value DESC, date DESC) AS RN
 FROM table
) x
WHERE x.RN = 1
1 голос
/ 14 августа 2010

Почему это НЕ работает?

update table
set flag = '1'
where id in (select id from (SELECT PK1, PK2, id, date,value, 
        ROW_NUMBER() OVER (PARTITION BY id ORDER BY value DESC, date DESC) AS RN 
FROM table) t where RN = 1)

РЕДАКТИРОВАТЬ: приведенный ниже оператор будет работать , если вы не хотите (или не можете в некоторых версиях sql) использоватьcte

Выше не будет работать, потому что, как говорит Мартин ниже, идентификатор все еще в списке.

однако ниже будет работать, если кто-то предпочитает не использовать cte. (Непочти столь же элегантно, как решение Мартина)

update table
set flag = '1'
where convert(varchar,PK1)+convert(varchar,PK2) in (select convert(varchar,PK1)+convert(varchar,PK2) from (SELECT PK1, PK2, id, date,value, 
        ROW_NUMBER() OVER (PARTITION BY id ORDER BY value DESC, date DESC) AS RN 
FROM table) t where RN = 1)
...