У меня есть таблица счетов со следующей структурой:
id | store_name | sum | payment_date
1 | Amazon | 10 | 11.05.2022
2 | Amazon | 20 | 11.05.2022
3 | Ebay | 15 | 11.05.2022
4 | AppleStore | 13 | 11.05.2022
5 | Google Play| 6 | 11.05.2022
Мне нужно выбрать все данные из таблицы и установить дополнительное поле «Приоритет» на основе суммы счета. Первые 2 строки получают приоритет 1, следующие 2 строки получают приоритет 2, остальные получают 0:
id | store_name | sum | payment_date | priority
2 | Amazon | 20 | 11.05.2022 | 1
3 | Ebay | 15 | 11.05.2022 | 1
4 | AppleStore | 13 | 11.05.2022 | 2
1 | Amazon | 10 | 11.05.2022 | 2
5 | Google Play| 6 | 11.05.2022 | 0
Кроме того, таблица содержит данные о счетах за разные дни (поле payment_date), и этот приоритет должен быть установлен на основе данных внутри каждого отдельного дня.


Упорядочите строки на каждый день, а затем назначьте приоритет на основе номера строки:
SELECT t.*,
CASE ROW_NUMBER()
OVER (PARTITION BY TRUNC(payment_date) ORDER BY sum DESC)
WHEN 1 THEN 1
WHEN 2 THEN 1
WHEN 3 THEN 2
WHEN 4 THEN 2
ELSE 0
END AS priority
FROM table_name t
Что для примера данных:
CREATE TABLE table_name (id, store_name, sum, payment_date) AS
SELECT 1, 'Amazon', 10, DATE '2022-05-11' FROM DUAL UNION ALL
SELECT 2, 'Amazon', 20, DATE '2022-05-11' FROM DUAL UNION ALL
SELECT 3, 'Ebay', 15, DATE '2022-05-11' FROM DUAL UNION ALL
SELECT 4, 'Apple Store', 13, DATE '2022-05-11' FROM DUAL UNION ALL
SELECT 5, 'Google Play', 6, DATE '2022-05-11' FROM DUAL;
Выходы:
ID STORE_NAME SUM PAYMENT_DATE PRIORITY 2 Amazon 20 2022-05-11 00:00:00 1 3 Ebay 15 2022-05-11 00:00:00 1 4 Apple Store 13 2022-05-11 00:00:00 2 1 Amazon 10 2022-05-11 00:00:00 2 5 Google Play 6 2022-05-11 00:00:00 0
дб <> рабочий пример здесь
@Evillain Хотя теоретически возможно, что вы сможете решить это с помощью FETCH NEXT n ROWS или ROWNUM, это почти наверняка будет менее эффективно, чем использование аналитической функции (особенно если вы хотите вычислить priority для каждого дня).
И если я хочу не строгий случай, когда 1, то 1, например: первые 20 строк помечаются приоритетом 1. Можно ли это сделать без внутреннего выбора?
@Evillain Вложенный подзапрос не является злом, поскольку вы будете использовать его только для фильтрации и не будете запрашивать какие-либо дополнительные таблицы. Тем не менее, да, просто используйте WHEN 1 THEN 1 WHEN 2 THEN 1 ... WHEN 20 THEN 1 WHEN 21 THEN 2 ... или CASE WHEN ROW_NUMBER() OVER (...) <= 20 THEN 1 WHEN ROW_NUMBER() OVER (...) <= 40 THEN 2 ELSE 0 END или используйте функцию DECODE.
Могу ли я сделать это как-то с помощью FETCH NEXT N ROWS? Или только с rownum? И мне нужно такое поле приоритета на основе поля payment_date. Например, для 10.05 у меня будет другой приоритет 1,2,0 строк