【问题标题】:calculate running total with a date range in where clause using oracle sql使用 oracle sql 在 where 子句中计算带有日期范围的运行总计
【发布时间】:2020-10-25 20:38:32
【问题描述】:

我有一张表,我想用 where 子句中的日期范围计算运行总计

+----------------+------------------+----------+
| Transaction ID | Transaction Date | Quantity |
+----------------+------------------+----------+
|              1 | 03-May-20        |        3 |
|              2 | 06-May-20        |        5 |
|              3 | 05-Jun-20        |       10 |
|              4 | 06-Jul-20        |        2 |
|              5 | 07-Aug-20        |        8 |
+----------------+------------------+----------+

现在我的 oracle sql 查询是

select
transaction_id,
transaction_date,
sum(quantity) over (order by transaction_date) as running_total

from table

where transaction_date >= '03-May-20' and transaction_date <= '06-Jul-20'

运行上面的查询后,我得到了下面的结果

+----------------+------------------+----------+---------------+
| Transaction ID | Transaction Date | Quantity | Running Total |
+----------------+------------------+----------+---------------+
|              1 | 03-May-20        |        3 |            28 |
|              2 | 06-May-20        |        5 |            33 |
|              3 | 05-Jun-20        |       10 |            43 |
|              4 | 06-Jul-20        |        2 |            45 |
+----------------+------------------+----------+---------------+

这是错误的,因为我想要的输出是:

| Transaction ID | Transaction Date | Quantity | Running Total |
+----------------+------------------+----------+---------------+
|              1 | 03-May-20        |        3 |             3 |
|              2 | 06-May-20        |        5 |             8 |
|              3 | 05-Jun-20        |       10 |            18 |
|              4 | 06-Jul-20        |        2 |            20 |
+----------------+------------------+----------+---------------+

请帮助我应该使用什么查询来计算 where 子句中的日期范围的运行总计。

您好,我尝试使用 to_date 函数,但得到的结果与上面相同(第 2 个表)。请参阅下面的查询,

select
transaction_id,
transaction_date,
sum(quantity) over (order by transaction_date) as running_total

from table

where transaction_date between TO_DATE('2019-03-01', 'YYYY-MM-DD') AND TO_DATE('2020-10-25', 'YYYY-MM-DD')

谢谢,

【问题讨论】:

  • 我看不出您的数据如何生成您指定的数据。数量之和大于您在表格中显示的数量。

标签: sql oracle


【解决方案1】:

您想要的输出(第 1 - 7 行中的示例数据;查询从第 8 行开始)。

SQL> with test (transaction_id, transaction_date, quantity) as
  2    (select 1, date '2020-05-03',  3 from dual union all
  3     select 2, date '2020-05-06',  5 from dual union all
  4     select 3, date '2020-06-05', 10 from dual union all
  5     select 4, date '2020-07-06',  2 from dual union all
  6     select 5, date '2020-08-07',  8 from dual
  7    )
  8  select transaction_id,
  9    transaction_date,
 10    quantity,
 11    sum(quantity) over (order by transaction_date) running_total
 12  From test
 13  where transaction_date between date '2020-05-03' and date '2020-07-06'
 14  order by transaction_id;

TRANSACTION_ID TRANSACTIO   QUANTITY RUNNING_TOTAL
-------------- ---------- ---------- -------------
             1 03.05.2020          3             3
             2 06.05.2020          5             8
             3 05.06.2020         10            18
             4 06.07.2020          2            20

SQL>

您遇到问题的原因是什么?我认为这是您将日期与字符串进行比较的事实('03-May-20' 是字符串,而不是日期)。 Oracle 尝试隐式转换数据类型;有时会成功,有时不会。例如,您的 03-May-20 可能是 2020 年 5 月 3 日或 2003 年 5 月 20 日。

始终可以控制您的数据。必要时使用日期,或者使用带有适当日期格式掩码的to_date 函数,或者使用日期文字(就像我一样)。

【讨论】:

    【解决方案2】:

    您的查询是“正确的”,但您的结果不是,它们包含预期的运行总计,但它从最终总计(包括事务 id 5)开始。您运行了不同的 SQL 语句。

    请注意,您不应将日期存储为字符串或将它们与字符串进行比较。也就是说,如果您当前的 NLS 日期格式设置(很容易更改)与您的字符串输入匹配,Oracle 将保存您的培根。如果您按字符串排序,您将得到完全不同的结果,您的结果具有预期的交易日期值,因此人们会假设这种比较已经奏效。您仍然应该修复您对日期的处理,但这不是这里的问题。

    【讨论】:

      【解决方案3】:

      其他事情正在发生。数据按日期正确汇总,因此日期排序似乎不是问题。

      总和从总和减去第一个值开始。所以,结果看起来像这个查询的结果:

      select transaction_id, transaction_date, quantity,
             total_quantity + sum(quantity) over (order by transaction_date)as running_total
      From (select t.*,
                   sum(quantity) over () - first_value(quantity) over (order by transaction_date) as total_quantity
            from test t
           ) t
      where transaction_date between date '2020-05-03' and date '2020-07-06'
      order by transaction_date;
      

      我无法解释为什么会发生这种情况。这可能是Oracle中的一个错误。或者这可能是您提出问题时过度简化查询的结果。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-10-21
        • 1970-01-01
        • 1970-01-01
        • 2019-07-15
        • 2019-08-13
        • 1970-01-01
        • 2021-10-05
        • 2011-10-25
        相关资源
        最近更新 更多