В SQL ранг() в зависимости от числа строк ()



Я запутался в различиях между ними. Выполнив следующий SQL возвращает меня два комплекта идентичный результат. Может кто-нибудь объяснить разницу?



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

7 ответов:

функции row_number : возвращает уникальное число для каждой строки, начиная с 1. Для строк, имеющих повторяющиеся значения, номера назначаются произвольно.

ранг : присваивает уникальный номер для каждой строки, начиная с 1, за исключением строк, имеющих повторяющиеся значения, в этом случае присваивается один и тот же рейтинг, и в последовательности появляется пробел для каждого повторяющегося рейтинга.

вы увидите разницу только в том случае, если у вас есть связи внутри раздела для определенного значения заказа.

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() (the RANK() функция не обрабатывается специально). Когда вам нужен сгенерированный ROW_NUMBER() на 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 |
+---+------------+------+------------+

совсем немного:

ранг строки равен единице плюс количество рангов, которые предшествуют рассматриваемой строке.

Row_number-это отдельный ранг строк, без каких-либо пробелов в рейтинге.

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

посмотреть в этом примере.

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', 'Синий', 'Зеленый')

Смотреть Всем

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

нужно понимать разные

кроме того, обратите внимание на порядок в разделе (например, используется стандартная база данных AdventureWorks) при использовании ранга.

выберите as1.SalesOrderID, as1.SalesOrderDetailID, RANK () OVER (Раздел по as1.Заказ SalesOrderID по as1.SalesOrderID) ranknoequal , RANK () OVER (разбиение на as1.Порядок значения salesorderid по в AS1.SalesOrderDetailId) ranknodiff от продаж.Таблицы salesorderdetail в AS1 Где SalesOrderId = 43659 заказать по SalesOrderDetailId;

дает результат:

SalesOrderID SalesOrderDetailID rank_same_as_partition rank_salesorderdetailid
43659 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 11
43659 12 1 12

но если изменить заказ для (используйте то :

выберите as1.SalesOrderID, as1.OrderQty, RANK () OVER (PARTITION BY в AS1.Заказ SalesOrderID по as1.SalesOrderID) ranknoequal, ранг() OVER (раздел по as1.Заказ SalesOrderID по as1.OrderQty ) rank_orderqty на продажи.Таблицы salesorderdetail в AS1, где значения salesorderid = 43659 заказа То;

выдает:

SalesOrderID OrderQty rank_salesorderid rank_orderqty
43659 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

обратите внимание, как меняется ранг, когда мы используем OrderQty (самый правый столбец второй таблицы) в порядке и как он меняется, когда мы используем 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  |
+--------+------+-----+----+

Comments

    Ничего не найдено.