Учитывая следующую таблицу, вопрос состоит в том, чтобы найти, например, верхний N C2 из каждого C1.
C1 C2
1 1
1 2
1 3
1 4
1 ...
2 1
2 2
2 3
2 4
2 ...
....
Так что, если N = 3, результат будет
C1 C2
1 1
1 2
1 3
2 1
2 2
2 3
....
Предлагаемые решения используют оконную функцию и разбиение на
Например,
SELECT rs.Field1,rs.Field2
FROM (
SELECT Field1,Field2, Rank()
over (Partition BY Section
ORDER BY RankCriteria DESC ) AS Rank
FROM table
) rs WHERE Rank <= 3
Я думаю, что он делаетсортирует, затем выбирает верхнюю N.
Однако если в некоторых категориях меньше N элементов, мы можем получить верхнюю N без сортировки, поскольку верхняя N должна включать все элементы в категории.
Приведенный выше запрос использует Rank ().Мой вопрос относится к другим оконным функциям, таким как row_num () или dens_rank ().
Есть ли способ игнорировать сортировку в случае?
Также я не уверен, может ли базовый движокОптимизировать регистр: учитывает ли внутренний раздел / порядок внешние ограничения where перед сортировкой.
Использование partition + order + где позволяет получить элемент top-N из каждой категории.Он отлично работает, если в каждой категории больше N элемента, но в противном случае имеет дополнительную стоимость сортировки.У меня вопрос, есть ли другой подход, который хорошо работает в обоих случаях.В идеале он делает следующее
for each category {
if # of element <= N:
continue
sort and get the top N
}
Например, но есть ли лучший SQL?
WITH table_with_count AS (
SELECT Field1, Field2, RankCriteria, count() over (PARTITION BY Section) as c
FROM table
),
rs AS (
SELECT Field1,Field2, Rank()
over (Partition BY Section
ORDER BY RankCriteria DESC ) AS Rank
FROM table_with_count
where c > 10
)
(SELECT Field1,Field2e FROM rs WHERE Rank <= 10)
union
(SELECT Field1,Field2 FROM table_with_count WHERE c <= 10)