Нахождение верхнего n для каждой уникальной строки
-
06-07-2019 - |
Вопрос
Я пытаюсь получить верхние N записей для каждой уникальной строки данных в таблице (я группирую по столбцам b,c и d, столбец a является уникальным идентификатором и столбцом e это оценка, из которой я хочу получить топ-1 в данном случае).
a b c d e
2 38 NULL NULL 141
1 38 NULL NULL 10
1 38 1 NULL 10
2 38 1 NULL 1
1 38 1 8 10
2 38 1 8 1
2 38 16 NULL 140
2 38 16 12 140
например ,из этих данных я хотел бы найти следующие строки:
a b c d e
2 38 NULL NULL 141
1 38 1 NULL 10
1 38 1 8 10
2 38 16 NULL 140
2 38 16 12 140
может кто-нибудь, пожалуйста, указать мне правильное направление, чтобы решить эту проблему?
Решение
Ваш пример не показывает, и вы не объясняете, как вы определяете, какая строка является "верхней", поэтому я поместил ??????в запросе, где вам нужно указать столбец ранжирования, например
a desc
например.В любом случае, это именно то, для чего предназначены аналитические функции в SQL Server 2005 и более поздних версиях.
declare @howmany int = 3;
with TRanked (a,b,c,d,e,rk) as (
select
a,b,c,d,e,
rank() over (
partition by b,c,d
order by ???????
)
from T
)
select a,b,c,d,e
from TRanked
where rk <= @howmany;
Другие советы
Нули - это боль, но что-то вроде этого:
select * from table1 t1
where a in (
select top 1 a from table1 t2
where (t1.b = t2.b or (t1.b is null and t2.b is null))
and (t1.c = t2.c or (t1.c is null and t2.c is null))
and (t1.d = t2.d or (t1.d is null and t2.d is null))
order by e desc
)
или еще лучше:
select * from (
select *, seqno = row_number() over (partition by b, c, d order by e desc)
from table1
) a
where seqno = 1
Я верю, что это сделает то, что вы сказали (расширяя идею от здесь):
select b,c,d,e,
rank() over
(partition by b,c,d order by e desc) "rank"
from t1 where rank < 5
Ваше здоровье.