[英]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.