Недавно я видел запрос, подобный приведенному ниже (ранг, плотное_ранг, с предложением group by). Я обнаружил, что предложение group by заставляет ранг вести себя как плотный ранг, и не смог найти документацию Microsoft об этом.
with FactTransactionHistory as
(
select 2 as ProductKey,'abc1' as trx
union
select 3 as ProductKey,'abc1' as trx
union
select 4 as ProductKey,'abc' as trx
union
select 4 as ProductKey,'abc2' as trx
union
select 4 as ProductKey,'abc3' as trx
union
select 5 as ProductKey,'abc' as trx
)
select ProductKey, DENSE_RANK() over(order by ProductKey) rowNumDense, RANK() over(order by ProductKey) rowNum
/*, count(*) recordCount*/
from FactTransactionHistory
group by ProductKey
Насколько я понимаю, если у over clause
есть partition by
, он будет упорядочен внутри раздела, поэтому значение ранга определяется внутри раздела.
Но в этом запросе нет partitition by
, поэтому order by
присутствует во всем наборе данных, и я не мог объяснить о функции ранжирования, почему она ведет себя как плотное ранг.
Не могли бы вы помочь объяснить, почему?
Примечание: если я удалю предложение group by
, rank и плотное_ранг будут показывать другое значение, как указано в документации.
Обе оконные функции работают с набором данных, полученным после применения группировки. Итак, когда присутствует предложение GROUP BY
, «весь набор данных» — это набор данных с разными значениями ProductKey.
Я обнаружил, что пункт
group by
заставляетrank
вести себя какdense rank
.
Эти две функции ранжирования отличаются только тем, как они обрабатывают ничьи. Здесь вы заказываете предложение over()
оконной функции с тем же столбцом, который используется в group by
, то есть ProductKey
. По своей природе агрегирование гарантирует отсутствие дубликатов ключа продукта, поэтому обе функции дают одинаковый результат.
Но в этом запросе нет
partition by
, поэтомуorder by
есть во всем наборе данных.
Это место, где ваши ожидания не оправдываются. Чтобы процитировать документы по предложению OVER
Если
PARTITION BY
не указан, функция обрабатывает все строки набора результатов запроса как одну группу.
Мой акцент. Именно строки результирующего набора, а не исходные строки, составляют здесь единый раздел.
Где
RANK
ведет себя какDENSE_RANK
? В единственном наборе данных они будут отличаться,RANK
(который вы ошибочно назвалиrowNum
) дает результат, отличный отDENSE_RANK
.