Условная группа SQL Oracle по

Я борюсь со следующей проблемой, буду благодарен за любую помощь! Мне нужно взять суммирование переменной но уровня группы по зависимостям от условия (см. 3.), это выходит за рамки моих знаний SQL.

Итак, мой запрос должен:

  1. Возьмите сумму СУММЫ по идентификатору и РАЗДЕЛИТЕ (см., например, ID_1, 100 + 50)
  2. С CUST, имеющим значение самой последней DATE (на уровне ID, SPLIT) (см., например, ID_1, A и B -> A)
  3. Если CUST имеет одинаковое значение DATE (на уровне ID, SPLIT), он должен сохранить оба значения, а также должно быть разделение для каждого CUST в AMOUNT (см., например, ID_3, 30 и 10 + 10).

Мой вымышленный набор данных выглядит так (скрипт для воссоздания см. внизу):

ИДЕНТИФИКАТОР РАСКОЛОТЬ CUST ДАТА КОЛИЧЕСТВО ID_1 РАЗДЕЛИТЬ_ДА А 01.05.2024 100 ID_1 SPLIT_NO А 01.04.2024 200 ID_1 РАЗДЕЛИТЬ_ДА Б 01.03.2024 50 ID_2 РАЗДЕЛИТЬ_ДА А 01.05.2024 50 ID_2 SPLIT_NO А 01.04.2024 300 ID_2 SPLIT_NO Б 01.03.2024 300 ID_3 РАЗДЕЛИТЬ_ДА Б 01.04.2024 90 ID_3 SPLIT_NO Б 01.04.2024 30 ID_3 SPLIT_NO А 01.04.2024 10 ID_3 SPLIT_NO А 01.03.2024 10

И окончательный результат запроса должен быть таким:

ИДЕНТИФИКАТОР РАСКОЛОТЬ CUST ДАТА КОЛИЧЕСТВО ID_1 РАЗДЕЛИТЬ_ДА А 01.05.2024 150 ID_1 SPLIT_NO А 01.04.2024 200 ID_2 РАЗДЕЛИТЬ_ДА А 01.05.2024 50 ID_2 SPLIT_NO А 01.04.2024 600 ID_3 РАЗДЕЛИТЬ_ДА Б 01.04.2024 90 ID_3 SPLIT_NO Б 01.04.2024 30 ID_3 SPLIT_NO А 01.04.2024 20

Спасибо вам всем!

Я пробовал использовать много разных операторов with, чтобы сделать это шаг за шагом, но без правильного результата. Используя оператор with, я могу объединить шаги 1 и 2, сначала суммируя по идентификатору и SPLIT, а затем объединяясь на основе самого последнего значения CUST VALUE, но это соединение является моей проблемой, поскольку оно делает шаг 3 невозможным.

WITH LatestDatePerID AS (
    SELECT ID, 
    "SPLIT",
           MAX(DATE_COLUMN) AS MAX_DATE
    FROM your_table_name
    GROUP BY ID, "SPLIT"
),
LatestCustPerID AS (
    SELECT t.ID, 
           t.CUST, 
           t."SPLIT",
           t.DATE_COLUMN, 
           t.AMOUNT
    FROM your_table_name t
    JOIN LatestDatePerID l ON t.ID = l.ID AND t.DATE_COLUMN = l.MAX_DATE and t."SPLIT" = l."SPLIT"
)
SELECT ID, 
       CUST,
       "SPLIT",
       DATE_COLUMN, 
       SUM(AMOUNT) AS AMOUNT
FROM LatestCustPerID
GROUP BY ID, "SPLIT", CUST, DATE_COLUMN
ORDER BY ID, DATE_COLUMN DESC;

Таким образом, он не суммирует другие игнорируемые строки. Я ломаю голову над этим.

Скрипт для воссоздания таблицы:

CREATE TABLE Test_Table_MM (
    ID VARCHAR2(10),
    SPLIT VARCHAR2(10),
    CUST VARCHAR2(10),
    DATE_COLUMN DATE,
    AMOUNT NUMBER
);

INSERT INTO Test_Table_MM (ID, SPLIT, CUST, DATE_COLUMN, AMOUNT) VALUES ('ID_1', 'SPLIT_YES', 'A', TO_DATE('05/01/2024', 'MM/DD/YYYY'), 100);
INSERT INTO Test_Table_MM (ID, SPLIT, CUST, DATE_COLUMN, AMOUNT) VALUES ('ID_1', 'SPLIT_NO', 'A', TO_DATE('04/01/2024', 'MM/DD/YYYY'), 200);
INSERT INTO Test_Table_MM (ID, SPLIT, CUST, DATE_COLUMN, AMOUNT) VALUES ('ID_1', 'SPLIT_YES', 'B', TO_DATE('03/01/2024', 'MM/DD/YYYY'), 50);
INSERT INTO Test_Table_MM (ID, SPLIT, CUST, DATE_COLUMN, AMOUNT) VALUES ('ID_2', 'SPLIT_YES', 'A', TO_DATE('05/01/2024', 'MM/DD/YYYY'), 50);
INSERT INTO Test_Table_MM (ID, SPLIT, CUST, DATE_COLUMN, AMOUNT) VALUES ('ID_2', 'SPLIT_NO', 'A', TO_DATE('04/01/2024', 'MM/DD/YYYY'), 300);
INSERT INTO Test_Table_MM (ID, SPLIT, CUST, DATE_COLUMN, AMOUNT) VALUES ('ID_2', 'SPLIT_NO', 'B', TO_DATE('03/01/2024', 'MM/DD/YYYY'), 300);
INSERT INTO Test_Table_MM (ID, SPLIT, CUST, DATE_COLUMN, AMOUNT) VALUES ('ID_3', 'SPLIT_YES', 'B', TO_DATE('04/01/2024', 'MM/DD/YYYY'), 90);
INSERT INTO Test_Table_MM (ID, SPLIT, CUST, DATE_COLUMN, AMOUNT) VALUES ('ID_3', 'SPLIT_NO', 'B', TO_DATE('04/01/2024', 'MM/DD/YYYY'), 30);
INSERT INTO Test_Table_MM (ID, SPLIT, CUST, DATE_COLUMN, AMOUNT) VALUES ('ID_3', 'SPLIT_NO', 'A', TO_DATE('04/01/2024', 'MM/DD/YYYY'), 10);
INSERT INTO Test_Table_MM (ID, SPLIT, CUST, DATE_COLUMN, AMOUNT) VALUES ('ID_3', 'SPLIT_NO', 'A', TO_DATE('03/01/2024', 'MM/DD/YYYY'), 10);

Пожалуйста, отредактируйте вопрос и включите минимальный воспроизводимый пример с: утверждениями CREATE TABLE и INSERT для вашего образца данных (в виде текста, который мы можем скопировать/вставить и выполнить, а НЕ изображений); подробное объяснение проблемы; и ожидаемый результат (опять же, в виде текста, а не изображений). Вам нужно объяснить, почему выходные данные выглядят так, потому что если вы GROUP BY id, split, то для id_1/SPLIT_NOcust будет A, а не B, и дата также не совпадает.

MT0 23.02.2024 17:17

Извиняюсь, не очень разбираюсь в публикации. Я добавил скрипт для воссоздания данных примера, в котором также исправил ошибку А и Б.

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

Ответы 1

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

Вы можете использовать аналитические функции:

SELECT id, 
       split,
       cust,
       date_column,
       CASE num_cust
       WHEN 1
       THEN total_amount
       ELSE total_cust_amount
       END AS amount
FROM   (
  SELECT t.*,
         COUNT(DISTINCT CASE rnk WHEN 1 THEN cust END)
           OVER (PARTITION BY id, split) AS num_cust
  FROM   (
    SELECT t.*,
           DENSE_RANK() OVER (PARTITION BY id, split ORDER BY date_column DESC) AS rnk,
           SUM(amount) OVER (PARTITION BY id, split) AS total_amount,
           SUM(amount) OVER (PARTITION BY id, split, cust) AS total_cust_amount
    FROM   test_table_mm t
  ) t
  WHERE  rnk = 1
)

Что для примера данных выводит:

ИДЕНТИФИКАТОР РАСКОЛОТЬ CUST DATE_COLUMN КОЛИЧЕСТВО ID_1 SPLIT_NO А 2024-04-01 00:00:00 200 ID_1 РАЗДЕЛИТЬ_ДА А 2024-05-01 00:00:00 150 ID_2 SPLIT_NO А 2024-04-01 00:00:00 600 ID_2 РАЗДЕЛИТЬ_ДА А 2024-05-01 00:00:00 50 ID_3 SPLIT_NO А 2024-04-01 00:00:00 20 ID_3 SPLIT_NO Б 2024-04-01 00:00:00 30 ID_3 РАЗДЕЛИТЬ_ДА Б 2024-04-01 00:00:00 90

рабочий пример

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