답변:
파티션 내에서 특정 순서 값과의 관계가있는 경우에만 차이점을 볼 수 있습니다.
RANK
그리고 DENSE_RANK
반면 순서 및 파티션 열 모두에 대해 동일한 값을 가진 모든 행은 동일한 결과로 끝날 것,이 경우에 결정적 ROW_NUMBER
임의로 (비는 결정 성)이 묶여 행 증가하는 결과를 부여한다.
예 : (모든 행이 동일 StyleID
하므로 동일한 파티션에 있고 해당 파티션 내에서 순서대로 첫 3 행이 묶여 있음 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
보고
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
세 개의 동일한 행에 대해 ROW_NUMBER
증분 이 증가하면 RANK
값이 동일하게 유지되어 도약하는 것을 알 수 4
있습니다. DENSE_RANK
또한 세 행 모두에 동일한 순위를 할당하지만 다음 고유 값에 값 2가 할당됩니다.
이 문서 간의 흥미로운 관계 커버 ROW_NUMBER()
와DENSE_RANK()
합니다 ( RANK()
함수 특별히 처리하지 않음). 당신이 생성 필요로 할 때 ROW_NUMBER()
A의 SELECT DISTINCT
문의는 ROW_NUMBER()
고유 한 값을 생성합니다 전에 그들이에 의해 제거되는 DISTINCT
키워드. 예를 들어이 쿼리
SELECT DISTINCT
v,
ROW_NUMBER() OVER (ORDER BY v) row_number
FROM t
ORDER BY v, row_number
...이 결과를 생성 할 수 있습니다 ( DISTINCT
효과가 없음).
+---+------------+
| V | ROW_NUMBER |
+---+------------+
| a | 1 |
| a | 2 |
| a | 3 |
| b | 4 |
| c | 5 |
| c | 6 |
| d | 7 |
| e | 8 |
+---+------------+
이 쿼리는 다음과 같습니다.
SELECT DISTINCT
v,
DENSE_RANK() OVER (ORDER BY v) row_number
FROM t
ORDER BY v, row_number
...이 경우에 원하는 것을 생성합니다.
+---+------------+
| V | ROW_NUMBER |
+---+------------+
| a | 1 |
| b | 2 |
| c | 3 |
| d | 4 |
| e | 5 |
+---+------------+
함수 의 ORDER BY
절에는 DENSE_RANK()
다른 모든 열이 필요합니다.SELECT DISTINCT
제대로 작동하려면 절.
논리적으로 창 기능 DISTINCT
이 적용 되기 전에 계산되기 때문 입니다. .
PostgreSQL / Sybase / SQL 표준 구문 사용 ( WINDOW
절) :
SELECT
v,
ROW_NUMBER() OVER (window) row_number,
RANK() OVER (window) rank,
DENSE_RANK() OVER (window) dense_rank
FROM t
WINDOW window AS (ORDER BY v)
ORDER BY v
... 당신은 얻을 것이다:
+---+------------+------+------------+
| V | ROW_NUMBER | RANK | DENSE_RANK |
+---+------------+------+------------+
| a | 1 | 1 | 1 |
| a | 2 | 1 | 1 |
| a | 3 | 1 | 1 |
| b | 4 | 4 | 2 |
| c | 5 | 5 | 3 |
| c | 6 | 5 | 3 |
| d | 7 | 7 | 4 |
| e | 8 | 8 | 5 |
+---+------------+------+------------+
상당히:
행의 순위는 1에 해당 행 앞에 오는 순위 수에 1을 더한 값입니다.
Row_number는 순위에 차이가없는 고유 한 행 순위입니다.
파티션 절이없는 간단한 쿼리 :
select
sal,
RANK() over(order by sal desc) as Rank,
DENSE_RANK() over(order by sal desc) as DenseRank,
ROW_NUMBER() over(order by sal desc) as RowNumber
from employee
산출:
--------|-------|-----------|----------
sal |Rank |DenseRank |RowNumber
--------|-------|-----------|----------
5000 |1 |1 |1
3000 |2 |2 |2
3000 |2 |2 |3
2975 |4 |3 |4
2850 |5 |4 |5
--------|-------|-----------|----------
이 예를보십시오.
CREATE TABLE [dbo].#TestTable(
[id] [int] NOT NULL,
[create_date] [date] NOT NULL,
[info1] [varchar](50) NOT NULL,
[info2] [varchar](50) NOT NULL,
)
일부 데이터 삽입
INSERT INTO dbo.#TestTable (id, create_date, info1, info2)
VALUES (1, '1/1/09', 'Blue', 'Green')
INSERT INTO dbo.#TestTable (id, create_date, info1, info2)
VALUES (1, '1/2/09', 'Red', 'Yellow')
INSERT INTO dbo.#TestTable (id, create_date, info1, info2)
VALUES (1, '1/3/09', 'Orange', 'Purple')
INSERT INTO dbo.#TestTable (id, create_date, info1, info2)
VALUES (2, '1/1/09', 'Yellow', 'Blue')
INSERT INTO dbo.#TestTable (id, create_date, info1, info2)
VALUES (2, '1/5/09', 'Blue', 'Orange')
INSERT INTO dbo.#TestTable (id, create_date, info1, info2)
VALUES (3, '1/2/09', 'Green', 'Purple')
INSERT INTO dbo.#TestTable (id, create_date, info1, info2)
VALUES (3, '1/8/09', 'Red', 'Blue')
1에 대해 동일한 값을 반복
dbo. # TestTable에 삽입 (ID, create_date, info1, info2) 값 (1, '1/1/09', 'Blue', 'Green')
모두 봐
SELECT * FROM #TestTable
결과를보십시오
SELECT Id,
create_date,
info1,
info2,
ROW_NUMBER() OVER (PARTITION BY Id ORDER BY create_date DESC) AS RowId,
RANK() OVER(PARTITION BY Id ORDER BY create_date DESC) AS [RANK]
FROM #TestTable
다른 이해가 필요
또한 RANK를 사용할 때 PARTITION (예 : Standard AdventureWorks db가 사용됨)의 ORDER BY에주의하십시오.
선택 as1.SalesOrderID, as1.SalesOrderDetailID, RANK () OVER (PARTITION BY as1.SalesOrderID ORDER BY as1.SalesOrderID) ranknoequal, RANK () OVER (PARTITION BY as1.SalesOrderID ORDER BY as1.SalesOrderDetailedDetailedDetailedDetailedDetailedDetailedDetailedDetaildDetailedDetaildDetaildDetailedDetaildDetailedDetaildDetailedDetaildDetailedDetailedDetailedDetailedDetaildder.com SalesOrderId = 43659 ORDER BY SalesOrderDetailId;
결과를 제공합니다 :
SalesOrderID SalesOrderDetailID rank_same_as_partition rank_salesorderdetailid그러나 주문을로 변경하면 (OrderQty 사용 :
select as1.SalesOrderID, as1.OrderQty, RANK () OVER (PARTITION BY as1.SalesOrderID ORDER BY as1.SalesOrderID) ranknoequal, RANK () OVER (PARTITION BY as1.SalesOrderID ORDER BY as1.OrderQty FROMEHERE.Orderqty FROME.Des.OrderQty FROME.Des.OrderQty FROMS.Des.OrderQty FROMS.Des.OrderQty FROMS.Detail. SalesOrderId = 43659 주문자 주문 수량;
제공합니다 :
SalesOrderID에 OrderQty rank_salesorderid rank_orderqtyORDER BY에서 OrderQty (가장 오른쪽 열의 두 번째 테이블)를 사용할 때 순위가 어떻게 변경되고 ORDER BY에서 SalesOrderDetailID (가장 오른쪽 열의 첫 번째 테이블)를 사용할 때 순위가 어떻게 변하는 지 확인하십시오.
나는 순위로 아무것도하지 않았지만 오늘 row_number ()로 이것을 발견했습니다.
select item, name, sold, row_number() over(partition by item order by sold) as row from table_name
필자의 경우 각 이름에 모든 항목이 있기 때문에 행 번호가 반복됩니다. 각 품목은 판매 된 수량에 따라 주문됩니다.
+--------+------+-----+----+
|glasses |store1| 30 | 1 |
|glasses |store2| 35 | 2 |
|glasses |store3| 40 | 3 |
|shoes |store2| 10 | 1 |
|shoes |store1| 20 | 2 |
|shoes |store3| 22 | 3 |
+--------+------+-----+----+