如何为范围内缺失的日期创建行?
How can I create rows for dates missing from a range?
我正在尝试获取查询提供的范围内所有日期的数据,但我只获取 table 中实际存在的日期 - 不会报告缺少的日期。我需要在 table 中为那些缺失的日期创建记录,其他列保留为空,然后将它们包含在结果中。
我的 table table_name
有这样的记录:
ID Name Date_only
---- ---- -----------
1234 xyz 01-Jan-2014
1234 xyz 02-Jan-2014
1234 xyz 04-Jan-2014
...
例如,对于 01-Jan-2014 到 04-Jan-2014 的范围,我的查询是:
select * from table_name
where id=1234
and (date_only >= '01-Jan-14' and date_only <= '04-Jan-14')
来自 Java 或直接查询,这显示三行,没有 2014 年 1 月 3 日的数据。
我需要一条语句将任何缺失日期的行插入到 table 和 return 所有四行的数据中。我该怎么做?
更新
仅当 table 或搜索范围 2-5 天内只有 1 条记录可用时,后续查询才有效,
SELECT LEVEL, to_date('2014-11-08','yyyy-mm-dd') + level as day_as_date FROM DUAL CONNECT BY LEVEL <= 10
.
更新 FIDDLE 示例
我得到的错误是:
我有 table 数据并执行了相同的查询然后我得到的错误是 ORA-02393: exceeded call limit on CPU usage, fiddle 例如: my owntable sqlfiddle example 提前致谢
您可以使用类似
的查询
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 天列表(根据您的需要进行调整)
接下来从 select
插入
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)
您可以在 purpose.The sql fiddle 此处使用以下 SQL 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:- 使用你的另一个 example.The sqlfiddle 是 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;
我正在尝试获取查询提供的范围内所有日期的数据,但我只获取 table 中实际存在的日期 - 不会报告缺少的日期。我需要在 table 中为那些缺失的日期创建记录,其他列保留为空,然后将它们包含在结果中。
我的 table table_name
有这样的记录:
ID Name Date_only
---- ---- -----------
1234 xyz 01-Jan-2014
1234 xyz 02-Jan-2014
1234 xyz 04-Jan-2014
...
例如,对于 01-Jan-2014 到 04-Jan-2014 的范围,我的查询是:
select * from table_name
where id=1234
and (date_only >= '01-Jan-14' and date_only <= '04-Jan-14')
来自 Java 或直接查询,这显示三行,没有 2014 年 1 月 3 日的数据。
我需要一条语句将任何缺失日期的行插入到 table 和 return 所有四行的数据中。我该怎么做?
更新
仅当 table 或搜索范围 2-5 天内只有 1 条记录可用时,后续查询才有效,
SELECT LEVEL, to_date('2014-11-08','yyyy-mm-dd') + level as day_as_date FROM DUAL CONNECT BY LEVEL <= 10
.
更新 FIDDLE 示例
我得到的错误是: 我有 table 数据并执行了相同的查询然后我得到的错误是 ORA-02393: exceeded call limit on CPU usage, fiddle 例如: my owntable sqlfiddle example 提前致谢
您可以使用类似
的查询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 天列表(根据您的需要进行调整)
接下来从 select
插入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)
您可以在 purpose.The sql fiddle 此处使用以下 SQL 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:- 使用你的另一个 example.The sqlfiddle 是 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;