2013-03-14 103 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

相关问题