На соревнованиях часто определяют места участников, исходя из суммы баллов за выступление. Бывает так, что разные участники набирают одинаковое количество баллов. В такой ситуации на одном месте оказывается несколько человек. В этом задании научимся определять места SQL запросом.
Проанализируем покупки клиентов. Для каждого товара найдем самую дешевую цену, по которой он продавался:
SELECT pi.product_id,
min (pi.price) AS min_price
FROM purchase_item pi
GROUP BY pi.product_id
ORDER BY min_price
# | product_id | min_price |
---|---|---|
1 | 7 | 4900.00 |
2 | 6 | 17800.00 |
3 | 4 | 21500.00 |
4 | 5 | 23500.00 |
5 | 3 | 26100.00 |
6 | 2 | 26100.00 |
7 | 8 | 38200.00 |
8 | 9 | 43800.00 |
9 | 10 | 76800.00 |
10 | 12 | 100000.00 |
11 | 11 | 1321800000.00 |
Обрати внимание на строки 5 и 6. Товары продавались по одной цене.
Попробуем ввести рейтинг самых дешевых товаров. Воспользуемся функцией row_number()
для проставления номеров в рейтинге:
SELECT pi.product_id,
row_number () over (order by min (pi.price)) AS position,
min (pi.price) AS min_price
FROM purchase_item pi
GROUP BY pi.product_id
ORDER BY min_price
# | product_id | position | min_price |
---|---|---|---|
1 | 7 | 1 | 4900.00 |
2 | 6 | 2 | 17800.00 |
3 | 4 | 3 | 21500.00 |
4 | 5 | 4 | 23500.00 |
5 | 3 | 5 | 26100.00 |
6 | 2 | 6 | 26100.00 |
7 | 8 | 7 | 38200.00 |
8 | 9 | 8 | 43800.00 |
9 | 10 | 9 | 76800.00 |
10 | 12 | 10 | 100000.00 |
11 | 11 | 11 | 1321800000.00 |
Смотрим на строки 5 и 6
# | product_id | position | min_price |
---|---|---|---|
5 | 3 | 5 | 26100.00 |
6 | 2 | 6 | 26100.00 |
Так дело не пойдет. Чем продукт 2 хуже продукта 3? У них должно быть одинаковое место в рейтинге.
В SQL
есть специальная функция ранжирования, которая проставит одинаковое место (ранг) для продуктов с одинаковой стоимостью. Она называется rank
.
Заменим row_number()
на rank()
и посмотрим на результат:
SELECT pi.product_id,
rank () over (order by min (pi.price)) AS position,
min (pi.price) AS min_price
FROM purchase_item pi
GROUP BY pi.product_id
ORDER BY min_price
# | product_id | position | min_price |
---|---|---|---|
1 | 7 | 1 | 4900.00 |
2 | 6 | 2 | 17800.00 |
3 | 4 | 3 | 21500.00 |
4 | 5 | 4 | 23500.00 |
5 | 3 | 5 | 26100.00 |
6 | 2 | 5 | 26100.00 |
7 | 8 | 7 | 38200.00 |
8 | 9 | 8 | 43800.00 |
9 | 10 | 9 | 76800.00 |
10 | 12 | 10 | 100000.00 |
11 | 11 | 11 | 1321800000.00 |
Продукты 2 и 3 теперь занимают одинаковую позицию в рейтинге.
# | product_id | position | min_price |
---|---|---|---|
5 | 3 | 5 | 26100.00 |
6 | 2 | 5 | 26100.00 |
Обрати внимание, что после 5 позиции в рейтинге сразу идет 7-я, т.к. на пятом месте располагаются два товара.
# | product_id | position | min_price |
---|---|---|---|
5 | 3 | 5 | 26100.00 |
6 | 2 | 5 | 26100.00 |
7 | 8 | 7 | 38200.00 |