Oracle 11g.七天内输出数据

jgovgodb  于 11个月前  发布在  Oracle
关注(0)|答案(1)|浏览(126)

在Oracle 11g中有一个Transactions表,例如:

CREATE TABLE transactions (id, sender_name, transaction_date, amount) AS
SELECT '1111', 'Alice', TIMESTAMP '2023-01-03 01:26:29', 700 FROM DUAL UNION ALL
SELECT '2222', 'Alice', TIMESTAMP '2023-01-05 04:26:29', 450 FROM DUAL UNION ALL
SELECT '3333', 'Alice', TIMESTAMP '2023-01-08 18:26:29', 1000 FROM DUAL UNION ALL
SELECT '4444', 'Alice', TIMESTAMP '2023-01-09 04:26:29', 200 FROM DUAL UNION ALL

SELECT '6666', 'Betty', TIMESTAMP '2023-03-12 15:26:29', 845 FROM DUAL UNION ALL
SELECT '7777', 'Betty', TIMESTAMP '2023-03-19 11:00:29', 300 FROM DUAL UNION ALL
  
SELECT '9999', 'Carol', TIMESTAMP '2023-08-26 01:26:29', 100 FROM DUAL UNION ALL
SELECT '8888', 'Carol', TIMESTAMP '2023-08-29 02:26:29', 501 FROM DUAL UNION ALL
SELECT '1234', 'Carol', TIMESTAMP '2023-09-10 03:26:29',  500 FROM DUAL UNION ALL
SELECT '4567', 'Carol', TIMESTAMP '2023-09-11 08:26:29',  501 FROM DUAL UNION ALL
SELECT '2345', 'Carol', TIMESTAMP '2023-09-17 04:26:29', 1001 FROM DUAL UNION ALL
SELECT '3456', 'Carol', TIMESTAMP '2023-09-30 05:26:29', 700 FROM DUAL UNION ALL
SELECT '5678', 'Carol', TIMESTAMP '2023-10-01 05:26:29', 200 FROM DUAL;

字符串
我为此道歉,但我需要两个选项来输出数据:))
1.选项:显示客户端(sender_name)的交易,在第一个transaction_date之后的七天内发送的总金额超过(amount) > 1000。在这种情况下,结果应该是:所有Alice的交易,因为第一次付款是03.01within seven days,直到09.01,她在这些天的交易总额为amountmore than 1000。所有Betty s事务也具有相同的逻辑。对于Carol事务10.09、11.09和17.09
2.Option:是否可以确定一周的开始(从星期一开始),并显示一周内(从星期一到星期日)进行的总金额超过1000(周内总金额)的客户交易?如果是,如何做到这一点。

64jmpszr

64jmpszr1#

对于选项1,您可以使用具有范围窗口的分析函数,首先计算过去7天的金额,然后在第二次计算中,计算未来一周中有多少行先前计算的总额超过1000,并仅筛选这些行:

SELECT id,
       sender_name,
       transaction_date,
       amount
FROM   (
  SELECT id,
         sender_name,
         transaction_date,
         amount,
         COUNT(CASE WHEN previous_weekly_amount > 1000 THEN 1 END) OVER (
             PARTITION BY sender_name
             ORDER BY transaction_date
             RANGE BETWEEN INTERVAL '0 00:00:00.000000000' DAY TO SECOND PRECEDING
                       AND INTERVAL '6 23:59:59.999999999' DAY TO SECOND FOLLOWING
         ) AS has_weekly_total_over_1000
  FROM   (
    SELECT id,
           sender_name,
           transaction_date,
           amount,
           SUM(amount) OVER (
             PARTITION BY sender_name
             ORDER BY transaction_date
             RANGE BETWEEN INTERVAL '6 23:59:59.999999999' DAY TO SECOND PRECEDING
                       AND INTERVAL '0 00:00:00.000000000' DAY TO SECOND FOLLOWING
           ) AS previous_weekly_amount
    FROM   transactions
  )
)
WHERE  has_weekly_total_over_1000 > 0;

字符串
对于样本数据,输出:
| ID|发送者名称|交易日期|量|
| --|--|--|--|
| 1111 |爱丽丝|2023-01-03 01:26:29.000000000| 700 |
| 2222 |爱丽丝|2023-01-05 04:26:29.00000000| 450 |
| 3333 |爱丽丝|2023-01-08 18:26:29.00000000| 1000 |
| 4444 |爱丽丝|2023-01-09 04:26:29.00000000| 200 |
| 6666 |贝蒂|2023-03-12 15:26:29.00000000| 845 |
| 7777 |贝蒂|2023-03-19 11:00:29.00000000| 300 |
| 1234 |卡罗尔|2023-09-10 03:26:29.00000000| 500 |
| 4567 |卡罗尔|2023-09-11 08:26:29.00000000| 501 |
| 2345 |卡罗尔|2023-09-17 04:26:29.00000000| 1001 |
选项2更简单,因为你只需要使用一个分析函数,并按发送者和ISO周进行聚合:

SELECT id,
       sender_name,
       transaction_date,
       amount
FROM   (
  SELECT id,
         sender_name,
         transaction_date,
         amount,
         SUM(amount) OVER (PARTITION BY sender_name, TRUNC(transaction_date, 'IW'))
           AS weekly_amount
  FROM   transactions
)
WHERE  weekly_amount > 1000;


对于样本数据,输出:
| ID|发送者名称|交易日期|量|
| --|--|--|--|
| 1111 |爱丽丝|2023-01-03 01:26:29.000000000| 700 |
| 2222 |爱丽丝|2023-01-05 04:26:29.00000000| 450 |
| 3333 |爱丽丝|2023-01-08 18:26:29.00000000| 1000 |
| 4567 |卡罗尔|2023-09-11 08:26:29.00000000| 501 |
| 2345 |卡罗尔|2023-09-17 04:26:29.00000000| 1001 |
fiddle

相关问题