我在创建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
是否有一些原生关键字可以使这项工作没有大量的连接和子查询?
谢谢,
盖瑞特
答案 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_date
和o.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 --
)
/