2013-03-14 83 views
2

我很難創建Oracle查詢來報告某些日子(每個月的第一個月的第一個月)中的訂單的歷史狀態。我搜查了搜索,發現沒有人提出類似的問題。這似乎是一個直截了當的問題,所以希望有人能幫助!這是我的例子:使用Oracle SQL檢索特定日期的訂單狀態

訂單表:

ORDER_NUMBER STATUS DATE 
    50001000  Created 01-15-2010 
    50001000  Released 02-20-2010 
    50001000  Completed 02-25-2010 
    50001000  Closed 03-10-2010 
    50001035  Created 01-20-2010 
    50001035  Released 01-25-2010 
    50001035  Completed 04-05-2010 
    50001035  Closed 05-30-2010 

所以我需要的輸出是每個訂單在每個月初的狀態。是這樣的:

DATE  ORDER_NUMBER STATUS 
    12-01-2009 
    01-01-2010 
    02-01-2010 50001000  Created 
    02-01-2010 50001035  Released 
    03-01-2010 50001000  Completed 
    03-01-2010 50001035  Released 
    04-01-2010 50001000  Closed 
    04-01-2010 50001035  Released 
    05-01-2010 50001000  Closed 
    05-01-2010 50001035  Completed 
    06-01-2010 50001000  Closed 
    06-01-2010 50001035  Closed 
    07-01-2010 50001000  Closed 
    07-01-2010 50001035  Closed 
    ..etc 

是否有一些本地關鍵字,可以使這個工作沒有大量的聯接和子查詢?

感謝,

加勒特

+0

聽起來像是你可以按月/年的分區,然後選擇與每個訂單的最大日期的狀態。也許這線程可能會有所幫助:http://stackoverflow.com/questions/561836/oracle-partition-by-keyword 此外,不應在2010年1月2日訂購'50001035'的狀態爲'Released',因爲它是01-25-2010發佈? – user1766760 2013-03-14 21:05:20

+0

是的,你是正確的我在我的例子中有一個錯誤,現在已經改變到02-01-2010發佈。謝謝! – Garrett 2013-04-02 15:50:43

回答

0

不知道,我明白你的樣本數據,但這裏的查詢,可以幫助你 - 你的約會比較每個月的第一天:

SELECT * FROM your_table 
WHERE your_date IN 
(
-- This query will give you the first day of each month -- 
Select Add_Months(Trunc(Sysdate,'YEAR'),Level-1) first_day_of_month 
    From dual 
Connect By Level <= 12 -- number of months in a year -- 
) 

/

+0

是的,這很好,我喜歡根據今天而不是硬編碼日期動態查詢。謝謝! – Garrett 2013-04-02 15:59:52

1

花了一段時間,但我認爲這將是你在找什麼:

select to_char(mf.month_first, 'MON-YYYY'), 
     o.order_name, 
     o.status 
    from (select add_months(to_date('01-DEC-2009'), level-1) month_first 
      from dual 
     connect by level <= 12) mf 
    left outer join orders o 
    on trunc(o.status_date, 'MM') <= mf.month_first 
where not exists(
    select 1 
     from orders 
     where ((trunc(status_date, 'MM') = trunc(o.status_date, 'MM') 
       and status_date < o.status_date) 
      or (trunc(status_date, 'MM') != trunc(o.status_date, 'MM') 
       and status_date >= o.status_date)) 
     and trunc(status_date, 'MM') <= mf.month_first 
     and order_name = o.order_name) 
order by mf.month_first, o.order_name 

上面的查詢可以確保如果在同一個月兩個狀態的變化,則顯示第一位的,這就是爲什麼status_dateo.status_date之間的比較發生兩次,一次當你在同一個月,一旦不同月份...

connect by level子選擇可以讓您通過指定月份的第一天(01-DEC-2009在這種情況下),該報告的持續時間/長度(12個月)改變的時間範圍。

我希望這是你之後的事情,儘管如果你有很多訂單,這很可能會創造很多行(特別是如果訂單在三月份完成,它會顯示出來作爲

這裏Closed,直到報告的結尾。是一個SQLFiddle看到它的工作。

+0

謝謝你的回覆,我在我們的服務器上運行這個查詢,看起來它超時。但我也查看了LEAD ... OVER函數(加入first_day_of_month BETWEEN status_date和next_status_date;並且還查看了MAX ... OVER ... PARTITION BY加入了status_date Garrett 2013-04-02 16:10:13