Oracle 按日期对订单进行分组并求和

Ran*_*der 1 sql oracle group-by

我的Orders桌子看起来像:

order_id     (number)
order_total  (number)
created_date (timestamp)
status       (varchar2)
Run Code Online (Sandbox Code Playgroud)

我的目标是获取一组行,其中每行代表该日期的所有订单,因此我尝试按日期对订单进行分组并获取order_total. 我还通过仅选择过去 30 天的订单来限制结果。

澄清一下,例如,如果过去 30 天内有 30 个订单都在唯一的日期,那么我将在结果中得到 30 行。另一个例子:如果 7 月 30 日有 10 个订单,7 月 31 日只有 1 个订单,那么我的目标是在结果集中获得 2 行,order_total第一行中所有 10 个订单的总和,第二行为当然有order_total31号的单单订单。

到目前为止我的尝试:

select
  sum(order_total) total_amount,
  to_char(created_date, 'DD/MM/YYYY') grouped_date
from
  orders
where
  status = 'Complete' and
  created_date >= (sysdate-30)
group by
  to_char(created_date, 'DD'), to_char(created_date, 'MM'), to_char(created_date, 'YYYY')
order by
  created_date asc
Run Code Online (Sandbox Code Playgroud)

这给出了一个错误:

ORA-00936: 缺少表达式

我尝试使用这个问题的解决方案,但我认为它不太适合我的场景(这是我的 group by 表达式的来源)。

Ale*_*ole 6

假设order_id不应该在那里,并且created_date有一个时间组件(看起来很可能是 a timestamp),您需要截断日期以在进行聚合时删除时间:

select
  sum(order_total) as total_amount,
  to_char(trunc(created_date), 'DD/MM/YYYY') as grouped_date
from
  orders
where
  status = 'Complete' and
  created_date >= trunc(sysdate-30)
group by
  trunc(created_date)
order by
  trunc(created_date) asc
Run Code Online (Sandbox Code Playgroud)

我还应用了truncwhere子句,否则它将忽略 30 天前午夜到您今天运行查询的任何时间之间的任何订单。我直接在 中使用了截断日期order by,而不是列别名,这样当您遇到月末时顺序是正确的 - 按字符串DD/MM/YYYY值排序会将 01/07/2013 放在 30/ 之前例如,2013 年 6 月。

快速SQL 小提琴