Różnicę zobaczysz tylko wtedy, gdy masz powiązania w obrębie partycji dla określonej wartości zamówienia.
RANK
i DENSE_RANK
są deterministyczne w tym przypadku, wszystkie wiersze o tej samej wartości zarówno dla kolumn porządkujących, jak i dzielących kończą się jednakowym wynikiem, podczas gdy ROW_NUMBER
arbitralnie (nie deterministycznie) przypiszą wynik rosnący do powiązanych wierszy.
Przykład: (Wszystkie wiersze mają to samo, StyleID
więc znajdują się w tej samej partycji i w tej partycji pierwsze 3 wiersze są powiązane, jeśli są uporządkowane według ID
)
WITH T(StyleID, ID)
AS (SELECT 1,1 UNION ALL
SELECT 1,1 UNION ALL
SELECT 1,1 UNION ALL
SELECT 1,2)
SELECT *,
RANK() OVER(PARTITION BY StyleID ORDER BY ID) AS 'RANK',
ROW_NUMBER() OVER(PARTITION BY StyleID ORDER BY ID) AS 'ROW_NUMBER',
DENSE_RANK() OVER(PARTITION BY StyleID ORDER BY ID) AS 'DENSE_RANK'
FROM T
Zwroty
StyleID ID RANK ROW_NUMBER DENSE_RANK
----------- -------- --------- --------------- ----------
1 1 1 1 1
1 1 1 2 1
1 1 1 3 1
1 2 4 4 2
Możesz zobaczyć, że dla trzech identycznych rzędów ROW_NUMBER
przyrosty, RANK
wartość pozostaje taka sama, a następnie przeskakuje 4
. DENSE_RANK
przypisuje również tę samą pozycję do wszystkich trzech wierszy, ale następnie następnej odrębnej wartości przypisuje się wartość 2.
W tym artykule opisano interesujący związek między
ROW_NUMBER()
iDENSE_RANK()
(RANK()
funkcja nie jest specjalnie traktowana). Kiedy trzeba wygenerowanyROW_NUMBER()
wSELECT DISTINCT
oświadczeniu,ROW_NUMBER()
będzie produkować różne wartości zanim zostaną one usunięte przezDISTINCT
słowa kluczowego. Np. To zapytanie... może dać ten wynik (
DISTINCT
nie ma efektu):Podczas gdy to zapytanie:
... produkuje to, co prawdopodobnie chcesz w tym przypadku:
Zauważ, że
ORDER BY
klauzulaDENSE_RANK()
funkcji będzie potrzebowała wszystkich innych kolumn zSELECT DISTINCT
klauzuli, aby działać poprawnie.Powodem tego jest to, że logicznie funkcje okna są obliczane przed
DISTINCT
zastosowaniem .Wszystkie trzy funkcje w porównaniu
Korzystanie ze standardowej składni PostgreSQL / Sybase / SQL (
WINDOW
klauzula):... dostaniesz:
źródło
Trochę:
Ranga rzędu wynosi jeden plus liczba rang, które występują przed danym rzędem.
Row_number to odrębna ranga wierszy, bez żadnej luki w rankingu.
http://www.bidn.com/blogs/marcoadf/bidn-blog/379/ranking-functions-row_number-vs-rank-vs-dense_rank-vs-ntile
źródło
Proste zapytanie bez klauzuli partycji:
Wynik:
źródło
Spójrz na ten przykład.
Wstaw trochę danych
Powtórz te same wartości dla 1
Look All
Spójrz na swoje wyniki
Musisz zrozumieć inaczej
źródło
Należy również zwrócić uwagę na ORDER BY w PARTITION (na przykład używana jest standardowa baza danych AdventureWorks) podczas korzystania z funkcji RANK.
Daje wynik:
SalesOrderID SalesOrderDetailID rank_same_as_partition rank_salesorderdetailid43659 1 1 1
43659 2 1 2
43659 3 1 3
43659 4 1 4
43659 5 1 5
43659 6 1 6
43659 7 1 7
43659 8 1 8
43659 9 1 9
43659 10 1 10
43659 11 1
4365 1 12
Ale jeśli zmień kolejność na do (użyj OrderQty:
Daje:
SalesOrderID Zamówienie Ilość rank_salesorderid rank_orderqty43659 1 1 1
43659 1 1 1
43659 1 1 1
43659 1 1 1
43659 1 1 1
43659 1 1 1
43659 2 1 7
43659 2 1 7
43659 3 1 9
43659 3 1 9
43659 4 1 11
43659 6 1 12
Zauważ, jak zmienia się Ranga, gdy używamy OrderQty (druga kolumna po prawej stronie) w ORDER BY i jak zmienia się, gdy używamy SalesOrderDetailID (pierwsza kolumna po prawej stronie) w ORDER BY.
źródło
Nie zrobiłem nic z rank, ale odkryłem to dzisiaj za pomocą row_number ().
Spowoduje to kilka powtarzających się numerów wierszy, ponieważ w moim przypadku każda nazwa zawiera wszystkie elementy. Każdy przedmiot zostanie uporządkowany według ilości sprzedanych.
źródło