Установить приоритет нового поля в SELECT SQL

У меня есть таблица счетов со следующей структурой:

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), и этот приоритет должен быть установлен на основе данных внутри каждого отдельного дня.

ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
0
0
31
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Упорядочите строки на каждый день, а затем назначьте приоритет на основе номера строки:

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;

Выходы:

IDSTORE_NAMESUMPAYMENT_DATEPRIORITY
2Amazon202022-05-11 00:00:001
3Ebay152022-05-11 00:00:001
4Apple Store132022-05-11 00:00:002
1Amazon102022-05-11 00:00:002
5Google Play62022-05-11 00:00:000

дб <> рабочий пример здесь

Могу ли я сделать это как-то с помощью FETCH NEXT N ROWS? Или только с rownum? И мне нужно такое поле приоритета на основе поля payment_date. Например, для 10.05 у меня будет другой приоритет 1,2,0 строк

Evillain 11.05.2022 10:27

@Evillain Хотя теоретически возможно, что вы сможете решить это с помощью FETCH NEXT n ROWS или ROWNUM, это почти наверняка будет менее эффективно, чем использование аналитической функции (особенно если вы хотите вычислить priority для каждого дня).

MT0 11.05.2022 10:34

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

Evillain 11.05.2022 15:10

@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.

MT0 11.05.2022 15:13

Другие вопросы по теме