Пронумеровать повторяющиеся значения по группам

Задача - пронумеровать повторяющиеся значения. Вот пример, в котором мы выводим все строки с повторяющимися значениями в столбце, отсортированные по столбцу Price:

   WITH DuplicateValue AS (
        SELECT Price, COUNT(*) AS CNT
        FROM Goods
        GROUP BY Price
        HAVING COUNT(*) > 1
   )
   SELECT ProductId, ProductName, Price 
   FROM Goods
   WHERE Price IN (SELECT Price FROM DuplicateValue)
   ORDER BY Price, ProductId;

Результат:

--------------------------
|  Id |  Name  |  Price  |
--------------------------
|  2  |  Pr 2  |   100   |
|  4  |  Pr 4  |   100   |
|  1  |  Pr 1  |   100   |
--------------------------
|  6  |  Pr 6  |   200   |
|  3  |  Pr 3  |   200   |
|  5  |  Pr 5  |   200   |
--------------------------
|  9  |  Pr 9  |   400   |
|  8  |  Pr 8  |   400   |
--------------------------

Теперь нужно создать переменную-порядковый номер продукта в конкретной группе цены:

--------------------------------
| No. |  Id |  Name  |  Price  |
--------------------------------
|  1  |  2  |  Pr 2  |   100   |
|  2  |  4  |  Pr 4  |   100   |
|  3  |  1  |  Pr 1  |   100   |
--------------------------------
|  1  |  6  |  Pr 6  |   200   |
|  2  |  3  |  Pr 3  |   200   |
|  3  |  5  |  Pr 5  |   200   |
--------------------------------
|  1  |  9  |  Pr 9  |   400   |
|  2  |  8  |  Pr 8  |   400   |
--------------------------------

Каким образом можно это сделать?


Ответы (2 шт):

Автор решения: Sergey Moiseenko
WITH DuplicateValue AS (
        SELECT Price, COUNT(*) AS CNT
        FROM Goods
        GROUP BY Price
        HAVING COUNT(*) > 1
   )
   SELECT ProductId, ProductName, Price
, row_number() over(partition by price order by ProductId) 
   FROM Goods
   WHERE Price IN (SELECT Price FROM DuplicateValue)
   ORDER BY Price, ProductId;
→ Ссылка
Автор решения: Akina
WITH 
cte AS ( SELECT *, 
                COUNT(*) OVER (PARTITION BY Price) cnt, 
                ROW_NUMBER() OVER (PARTITION BY Price ORDER BY id) `No.`
         FROM Goods )
SELECT `No.`, Id, Name, Price
FROM cte
WHERE cnt > 1
ORDER BY Price, `No.`
→ Ссылка