如何为范围中缺少的日期创建行?

时间:2015-01-24 11:22:53

标签: java sql oracle oracle11g subquery

我正在尝试获取由我的查询提供的范围内的所有日期的数据,但我只获取实际存在于我的表中的日期 - 不报告缺少的日期。我需要在表中为那些缺少的日期创建记录,其他列保留为null,然后将它们包含在结果中。

我的表table_name的记录如下:

  ID  Name  Date_only
----  ----  -----------
1234  xyz   01-Jan-2014
1234  xyz   02-Jan-2014
1234  xyz   04-Jan-2014
...

例如,对于2014年1月1日至2014年1月4日的范围,我的查询是:

select * from table_name
where id=1234
and (date_only >= '01-Jan-14' and date_only <= '04-Jan-14')

从Java或直接查询,这显示三行,没有2014年1月3日的数据。

我需要一个语句将任何缺少日期的行插入表中,并返回所有四行的数据。我怎么能这样做?

更新

仅当表中只有1条记录或搜索范围2-5天

时,后续查询才有效

SELECT LEVEL, to_date('2014-11-08','yyyy-mm-dd') + level as day_as_date FROM DUAL CONNECT BY LEVEL <= 10

更新有问题的例子

我得错误是: 我有表数据和相同的查询执行然后我得到错误是 ORA-02393:超出CPU使用率的呼叫限制,小提琴示例是:my owntable sqlfiddle example。提前谢谢

2 个答案:

答案 0 :(得分:2)

你可以使用下面的SQL来达到你的目的。这里的sql fiddle http://sqlfiddle.com/#!4/3ee61/27

with start_and_end_dates as (select min(onlydate) min_date
,max(onlydate) max_date
from mytable
where id='1001'
and onlydate >= to_date('01-Jan-2015','dd-Mon-YYYY') 
and onlydate <= to_date('04-Jan-2015','dd-Mon-YYYY')),

missing_dates as (select min_date + level-1  as date_value 
from start_and_end_dates connect by level <=(max_date - min_date) + 1)

select distinct id,name,date_value
from mytable,missing_dates
where id='1001'
order by date_value

EDIT1: - 使用您的其他示例.startlfiddle是http://sqlfiddle.com/#!4/4c727/16

with start_and_end_dates as (select min(onlydate) min_date
,max(onlydate) max_date
from mytable
where name='ABCD'),

missing_dates as (select min_date + level-1  as date_value 
from start_and_end_dates connect by level <=(max_date - min_date) + 1)

select distinct id,name,date_value
from mytable,missing_dates
where name='ABCD'
order by date_value;

答案 1 :(得分:1)

您可以使用

之类的查询
SELECT LEVEL, to_date('2014-01-01','yyyy-mm-dd') + level as day_as_date
  FROM DUAL
CONNECT BY LEVEL <= 1000

从2014年1月1日起获得1000天的清单(根据您的需要调整)

接下来从选择

进行插入
INSERT INTO table_name (date_only)
SELECT day_as_date FROM (<<THE_QUERY_ABOVE>>)
WHERE day_as_date NOT IN (SELECT date_only FROM table_name)