SQL Oracle 条件分组依据

问题描述 投票:0回答:1

我正在努力解决以下问题,任何帮助将不胜感激! 我需要对变量求和,但分组级别取决于条件(参见 3.),这超出了我对 SQL 的了解。

所以我的查询应该:

  1. 计算每个 ID 和 SPLIT 的 AMOUNT 的总和(参见 f.e. ID_1, 100 + 50)
  2. CUST 具有最近 DATE 的值(在 ID、SPLIT 级别)(参见 f.e ID_1、A 和 B -> A)
  3. 如果 CUST 具有相同的 DATE 值(在 ID、SPLIT 级别),则应保留这两个值,并且每个 CUST 还应按 AMOUNT 进行拆分(请参阅 f.e. ID_3、30 和 10 + 10)

我的虚构数据集如下所示(重新创建的脚本见底部):

身份证 分裂 客户 日期 金额
ID_1 分割_是 A 2024年5月1日 100
ID_1 SPLIT_NO A 2024年4月1日 200
ID_1 分割_是 B 2024年3月1日 50
ID_2 分割_是 A 2024年5月1日 50
ID_2 SPLIT_NO A 2024年4月1日 300
ID_2 SPLIT_NO B 2024年3月1日 300
ID_3 分割_是 B 2024年4月1日 90
ID_3 SPLIT_NO B 2024年4月1日 30
ID_3 SPLIT_NO A 2024年4月1日 10
ID_3 SPLIT_NO A 2024年3月1日 10

最终查询结果应该是这样的:

身份证 分裂 客户 日期 金额
ID_1 分割_是 A 2024年5月1日 150
ID_1 SPLIT_NO A 2024年4月1日 200
ID_2 分割_是 A 2024年5月1日 50
ID_2 SPLIT_NO A 2024年4月1日 600
ID_3 分割_是 B 2024年4月1日 90
ID_3 SPLIT_NO B 2024年4月1日 30
ID_3 SPLIT_NO A 2024年4月1日 20

谢谢大家!

我尝试使用很多不同的 with 语句来一步步完成,但没有正确的结果。使用 with 语句,我可以通过首先对每个 ID 和 SPLIT 进行求和,然后根据最新的 CUST VALUE 进行连接来解决步骤 1 和 2,但这种连接是我的问题,因为它使步骤 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);
sql oracle group-by conditional-statements
1个回答
0
投票

您可以使用分析函数:

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
)

对于样本数据,输出:

身份证 分裂 客户 DATE_COLUMN 金额
ID_1 SPLIT_NO A 2024-04-01 00:00:00 200
ID_1 分割_是 A 2024-05-01 00:00:00 150
ID_2 SPLIT_NO A 2024-04-01 00:00:00 600
ID_2 分割_是 A 2024-05-01 00:00:00 50
ID_3 SPLIT_NO A 2024-04-01 00:00:00 20
ID_3 SPLIT_NO B 2024-04-01 00:00:00 30
ID_3 分割_是 B 2024-04-01 00:00:00 90

小提琴

© www.soinside.com 2019 - 2024. All rights reserved.