按月/年重组查询到组

时间:2014-03-31 09:12:47

标签: sql oracle-sqldeveloper

我有一个包含数百万行信息的数据库,跟踪订单在整个系统中的进度。从头到尾,订单可以通过2到20个系统。此旅程的每个部分都将记录在数据库中,例如

ORDER ID        SOURCE        DESTINATION        TIMESTAMP
10               Sys 1          Sys 2            01-Jan-14
10               Sys 2          Sys 3            01-Jan-14
10               Sys 3          Sys 4            03-Jan-14
10               Sys 4          Sys 5            07-Jan-14

时间戳记录离开该系统的订单。

我写了一个查询来确定每个订单的长度:

Select ORDERID, 1 + TRUNC(MAX(TIMESTAMP)) - TRUNC(MIN(TIMESTAMP))
from DATABASE GROUP BY ORDERID

这样可以正常工作,而上述订单会产生7天。当我在数据库中的每个元组上运行此查询时,我得到数据库中每个订单的平均端到端进度时间。然后,我可以使用所有这些单独的总计来查找整体平均订单时间。

这一切都很好,但我现在希望能够将其分解为单个月/年配对,这样我就可以有效地查看系统中的平均时间长度是否在给定月份内增加或减少

我对SQL很缺乏经验,我真的不知道从哪里开始。我如何编写一个跟踪任何订单的开始日期的查询,并查看它在系统中的停留时间,从而生成系统每月/每年组合的总天数

示例数据

目前,上面的查询会生成一系列这样的元组:

Order Id    Days in System
0145240 1
10000   1
10001   1
10003   130
10004   3
10007   1
10008   13
10009   1
10010   1
然后,我可以找到所有这些信息的平均值。我真正想要的是能够做到这样的事情:

ORDER ID        SOURCE        DESTINATION        TIMESTAMP
10               Sys 1          Sys 2            01-Jan-14
10               Sys 2          Sys 3            01-Jan-14
10               Sys 3          Sys 4            03-Jan-14
10               Sys 4          Sys 5            07-Jan-14
11               Sys 1          Sys 2            01-Feb-14
11               Sys 2          Sys 3            03-Mar-14
12               Sys 1          Sys 2            04-Mar-14           
12               Sys 2          Ssy 3            05-Mar-14
13               Sys 1          Sys 2            07-Mar-14
13               Sys 2          Sys 3            14-Mar-14

想象一下,以上所有都是已完成的订单。

订单ID 10:从头到尾花了7天时间 订单ID 11:从头到尾花了31天 订单ID 12:从头到尾花了2天时间 订单ID 13:从头到尾花了8天时间。

OrderId 10是1月份唯一的订单,订单ID 11仅在2月份订购,订单ID 12和13都在3月份订购。因此,理想情况下,我想设计的查询将产生以下内容:

Jan 2014:    Average = 7
Feb 2014:    Average = 31
Mar 2014:    Average = 5 (i.e. (2 + 8) / 2)

2 个答案:

答案 0 :(得分:2)

按月计算

Select ORDERID, 
       to_char(to_date(Timestamp, 'DD-MM-YYYY'), 'Month'),
       1 + TRUNC(MAX(TIMESTAMP)) - TRUNC(MIN(TIMESTAMP)) as duration
from DATABASE GROUP BY ORDERID, to_char(to_date(Timestamp, 'DD-MM-YYYY'), 'Month')
Order By ORDERID,duration

同样,您可以从时间戳日期列中提取年份,并按订单ID和年份分组,以按年度顺序跟踪每个订单ID的持续时间。

答案 1 :(得分:1)

您可以查看分析函数,但一种相当简单的方法是添加' start'日期(这有点令人困惑,因为它似乎是订单离开第一个系统时的时间戳,而不是当它到达那里时?):

select orderid, min(timestamp) as first_seen,
  1 + trunc(max(timestamp)) - trunc(min(timestamp)) as duration
from database
group by orderid
order by orderid;

有一些额外的数据可能会给你:

   ORDERID FIRST_SEEN                     DURATION
---------- ---------------------------- ----------
        10 01-JAN-14 09.00.00.000000000          7 
        11 01-JAN-14 09.00.00.000000000          2 
        12 31-JAN-14 09.00.00.000000000          3 
        13 01-FEB-14 09.00.00.000000000          2 

然后,您可以将其用作子查询,并通过在第一次看到'的第一个月的第一个日期进行分组。日期:

select trunc(first_seen, 'MM') as month,
  avg(duration) as duration
from (
  select orderid, min(timestamp) as first_seen,
    1 + trunc(max(timestamp)) - trunc(min(timestamp)) as duration
  from database group by orderid
)
group by trunc(first_seen, 'MM')
order by trunc(first_seen, 'MM');

MONTH       DURATION
--------- ----------
01-JAN-14          4 
01-FEB-14          2 

SQL Fiddle

呼叫表格'数据库'有点令人困惑,因为它是keyword(虽然没有保留,所以它是合法的)。并拨打专栏'时间戳'也有点奇怪,特别是如果它实际上是date而不是timestamp - 它不清楚你的实际表格有哪些。但是,由于你已经更改了发布的名称,这是没有实际意义的。

with your expanded sample data

   ORDERID FIRST_SEEN                     DURATION
---------- ---------------------------- ----------
        10 01-JAN-14 00.00.00.000000000          7 
        11 01-FEB-14 00.00.00.000000000         31 
        12 04-MAR-14 00.00.00.000000000          2 
        13 07-MAR-14 00.00.00.000000000          8 

MONTH       DURATION
--------- ----------
01-JAN-14          7 
01-FEB-14         31 
01-MAR-14          5