[英]Restructure query to group by month/year
我有一个包含数百万行信息的数据库,跟踪订单在整个系统中的进度。 从头到尾,订单可以通过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)
按月计算
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
同样,您可以从时间戳日期列开始延长年份,按照orderid和年份分组,以按年度顺序跟踪每个订单ID的持续时间。
您可以查看分析函数,但是一个相当简单的方法是添加“开始”日期(这有点令人困惑,因为它似乎是订单离开第一个系统时的时间戳,而不是它到达那里的时间?) :
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小提琴 。
调用表'数据库'有点令人困惑,因为它是一个关键字 (虽然没有保留,所以它是合法的)。 调用列'timestamp'也有点奇怪,特别是如果它实际上是一个date
而不是timestamp
- 不清楚你的实际表有哪些。 但是,当你改变发布的名字时,这是没有实际意义的。
或者使用扩展的样本数据 :
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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.