복붙노트

[SQL] ROW_NUMBER 대 SQL RANK () ()

SQL

ROW_NUMBER 대 SQL RANK () ()

나는이 차이에 대해 혼란스러워하고 있습니다. 다음 SQL을 실행하면 나에게 두 idential 결과 세트를 가져옵니다. 누군가가 차이를 설명시겠습니까?

SELECT ID, [Description], RANK()       OVER(PARTITION BY StyleID ORDER BY ID) as 'Rank'      FROM SubStyle
SELECT ID, [Description], ROW_NUMBER() OVER(PARTITION BY StyleID ORDER BY ID) as 'RowNumber' FROM SubStyle

해결법

  1. ==============================

    1.ROW_NUMBER가 : 중복 값이 ​​행의 1로 시작하는 각 행에 대해 고유 번호를 돌려 번호가 arbitarily 할당됩니다.

    ROW_NUMBER가 : 중복 값이 ​​행의 1로 시작하는 각 행에 대해 고유 번호를 돌려 번호가 arbitarily 할당됩니다.

    순위 : 할당 동일한 순위가 할당 된 경우, 중복 값이 ​​행 및 순위 각 복제에 대한 시퀀스에 갭이 나타날 제외한 1로 시작하는 각각의 행에 대한 고유 번호.

  2. ==============================

    2.특정 주문 값에 대한 파티션 내에서 관계있는 경우에만 차이를 볼 수 있습니다.

    특정 주문 값에 대한 파티션 내에서 관계있는 경우에만 차이를 볼 수 있습니다.

    ROW_NUMBER 임의로 (비는 결정 성)이 묶여 행 증가하는 결과를 할당하는 반면 RANK와 DENSE_RANK는,이 경우에 동일한 결과로 끝날 것 순서 및 파티션 열 모두에 대해 동일한 값을 갖는 모든 행 결정적이다.

    예 : (모든 행하므로 동일한 StyleID가 동일한 파티션 및 ID에 의해 지시 될 때 상기 제 3 개 행이 묶여 파티션 내에있다)

    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
    

    당신은 3 개의 동일한 행 ROW_NUMBER 단위를 들어, RANK 값이 모든 세 개의 행에 동일한 순위를 할당하지만 다음 별개의 값이 2의 값을 할당은 4 DENSE_RANK로 도약 한 후 동일하게 유지 것을 볼 수 있습니다.

  3. ==============================

    3.이 문서 ROW_NUMBER ()와 DENSE_RANK () (랭크 () 함수는 특별히 처리되지 않음) 간의 흥미로운 관계를 다룬다. 당신이 SELECT DISTINCT 문에 발생 ROW_NUMBER ()를 필요로 할 때 그들이 DISTINCT 키워드 제거하기 전에 ROW_NUMBER ()는 고유 한 값을 생성합니다. 예를 들면 이 쿼리

    이 문서 ROW_NUMBER ()와 DENSE_RANK () (랭크 () 함수는 특별히 처리되지 않음) 간의 흥미로운 관계를 다룬다. 당신이 SELECT DISTINCT 문에 발생 ROW_NUMBER ()를 필요로 할 때 그들이 DISTINCT 키워드 제거하기 전에 ROW_NUMBER ()는 고유 한 값을 생성합니다. 예를 들면 이 쿼리

    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 |
    +---+------------+
    

    DENSE_RANK () 함수의 ORDER BY 절은 제대로 작동하려면 SELECT DISTINCT 절에서 다른 모든 열을 필요합니다.

    그 이유는 구별되는 적용 전에 논리적으로, 윈도우 함수가 계산된다는 것이다.

    PostgreSQL을 /베이스 / 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 |
    +---+------------+------+------------+
    
  4. ==============================

    4.상당히:

    상당히:

    행의 순위는 하나 플러스 문제의 행의 전에 와서 계급의 수입니다.

    ROW_NUMBER는 순위에 어떤 차이없이, 행의 고유 한 순위입니다.

    http://www.bidn.com/blogs/marcoadf/bidn-blog/379/ranking-functions-row_number-vs-rank-vs-dense_rank-vs-ntile

  5. ==============================

    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 반복 같은 값

    봐 모든

    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
    

    다른를 이해할 필요가있다

  6. ==============================

    6.RANK를 사용하는 경우 또한, 파티션에 ORDER BY에 지불주의 (표준의 AdventureWorks DB를 예를 들어 사용됩니다).

    RANK를 사용하는 경우 또한, 파티션에 ORDER BY에 지불주의 (표준의 AdventureWorks DB를 예를 들어 사용됩니다).

    결과를 제공합니다 :

    그러나 (사용 OrderQty에 의해 변경 주문하는 경우 :

    제공합니다 :

    우리가 ORDER BY에서 OrderQty (가장 오른쪽 두 번째 테이블)를 사용하고 우리가 ORDER BY에서 SalesOrderDetailID (오른쪽 열 첫 번째 테이블)를 사용할 때 변경하는 방법을 때 순위가 어떻게 변하는 지 알 수 있습니다.

  7. ==============================

    7.나는 순위에 아무 짓도하지 않은,하지만 난 ROW_NUMBER와이 오늘 발견 ().

    나는 순위에 아무 짓도하지 않은,하지만 난 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  |
    +--------+------+-----+----+
    
  8. from https://stackoverflow.com/questions/7747327/sql-rank-versus-row-number by cc-by-sa and MIT license