Как создать строки для дат, отсутствующих в диапазоне?

1

Я пытаюсь получить данные для всех дат в диапазоне, предоставленном моим запросом, но я получаю только даты, которые действительно существуют в моей таблице. Отсутствующие даты не сообщаются. Мне нужно создать записи в таблице для тех отсутствующих дат, а остальные столбцы останутся пустыми, а затем включить их в результаты.

В моей таблице table_name есть записи:

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

Например, для диапазона с 01 января по 2014 г. по 04 января 2014 г. мой запрос:

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

С Java или запрошенным напрямую это показывает три строки, без данных за 03-янв-2014.

Мне нужен один оператор для вставки строк для любых отсутствующих дат в таблицу и возврата данных для всех четырех строк. Как я могу это сделать?

ОБНОВИТЬ

Следующий запрос работал только в том случае, если только одна запись доступна в таблице ИЛИ диапазоне поиска 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: превысил лимит на использование ЦП, пример скрипта: мой собственный пример sqlfiddle.

  • 0
    Показанный вами запрос не будет соответствовать ни одной из ваших трех записей - или любой записи, поле не может быть равным двум вещам одновременно. Вы действительно хотите вставить строку в таблицу для пропущенных дат в диапазоне - и если да, то с какими значениями для других столбцов? - или просто включить его в набор результатов с пустым значением?
  • 0
    спасибо @Alex Poole, извините, теперь обновил мой вопрос, мне нужен набор результатов с 4 записями и обновить эту запись также в таблице.
Показать ещё 3 комментария
Теги:
oracle11g
subquery

2 ответа

2
Лучший ответ

вы можете использовать приведенный ниже SQL для своей цели. Скрипт 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: - Использование другого примера. 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;
  • 0
    спасибо @ psaraj12 ..
  • 0
    Для with start_and_end_dates as (select min(to_date(fromDate,'dd-MM-yyyy')) min_date,max(to_date(ToDate,'dd-MM-yyyy')) max_date from mytable where name='ABCD') ....etc : with start_and_end_dates as (select min(to_date(fromDate,'dd-MM-yyyy')) min_date,max(to_date(ToDate,'dd-MM-yyyy')) max_date from mytable where name='ABCD') ....etc . Д.
Показать ещё 1 комментарий
1

Вы можете использовать запрос типа

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

чтобы получить список из 1000 дней с 1 января 2014 года (приспосабливайтесь к вашим потребностям)

Затем сделайте вставку из

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)
  • 0
    спасибо @ ms32035, это работает, но если я взял 10, его показ более чем 10, и это продолжается ...
  • 0
    Странный. Выбор строки в порядке. Посмотри на скрипку
Показать ещё 7 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню