1

我的Orders桌子看起来像:

order_id     (number)
order_total  (number)
created_date (timestamp)
status       (varchar2)

我的目标是获得一组行,其中每行代表该日期的所有订单,因此我尝试按日期对订单进行分组并获得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

这给出了一个错误:

ORA-00936: 缺少表达式

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

4

1 回答 1

5

Assuming order_id should not be there, and that created_date has a time component (which seems likely as it's a timestamp), you need to truncate the date to remove the time when doing the aggregation:

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

I've also applied trunc to the where clause, otherwise it would ignore any orders 30 days ago between midnight and whatever time you ran the query today. And I've used the trunc'd date directly in the order by, rather than the column alias, so that the order is right when you go across a month-end - ordering by the DD/MM/YYYY string value would put 01/07/2013 before 30/06/2013, for example.

Quick SQL Fiddle.

于 2013-07-31T10:32:09.297 回答