使用Oracle SQL检索特定日期的订单状态

时间:2013-03-14 20:26:32

标签: sql oracle

我在创建Oracle查询时遇到困难,无法在某些日子(每个月的第一个月)报告订单的历史状态。我搜索并搜索过,发现没有人问过类似的问题。这似乎是一个直截了当的问题所以希望有人可以提供帮助!这是我的例子:

ORDERS表:

    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

是否有一些原生关键字可以使这项工作没有大量的连接和子查询?

谢谢,

盖瑞特

2 个答案:

答案 0 :(得分: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之间的比较发生两次的原因,一次是针对何时#&# 39;在同一个月,一次不同的月份......

connect by level子选择允许您通过指定月份的第一个日期(本例中为01-DEC-2009)和报告的持续时间/长度(12个月来更改日期范围)。

我希望这就是你所追求的,虽然我不得不说如果你有很多订单,这很可能会创造很多行(特别是如果订单在3月份完成,那么&#39;在报告结束之前将显示为Closed

这里有一个SQLFiddle,看它有效。

答案 1 :(得分: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 --
)

/