Рекурсивные РТЫ предоставления SQL 01790

Используя выпуск 2 11 г Oracle, следующий запрос дает РТЫ 01790: выражение должно иметь тот же тип данных как соответствующее выражение:

with intervals(time_interval) AS
 (select trunc(systimestamp)
    from dual
  union all
  select (time_interval + numtodsinterval(10, 'Minute'))
    from intervals
   where time_interval < systimestamp)
select time_interval from intervals;

Ошибка предполагает, что тип данных обоих подзапросов ОБЪЕДИНЕНИЯ ВСЕ возвращают различные типы данных.

Даже если я бросил для ДОБАВЛЕНИЯ МЕТКИ ВРЕМЕНИ в каждом из подзапросов, то я получаю ту же ошибку.

Что я пропускаю?

Править: Я не ищу ПОДКЛЮЧЕНИЕ заменой.

5
задан 3 revs, 2 users 100% 6 April 2010 в 20:02
поделиться

2 ответа

На мой взгляд, "рекурсивная факторизация подзапросов" не работает в 11g R2 для запросов со столбцом даты или времени.

with test(X) as
(
  select to_date('2010-01-01','YYYY-MM-DD') from dual
  union all (
    select (X + 1) from test where X <= to_date('2010-01-10','YYYY-MM-DD') 
  )
)
select * from test;

ORA-01790

используйте приведение для преобразования типа данных:

with test(X) as
(
  select cast(to_date('2010-01-01','YYYY-MM-DD') as date) from dual
  union all (
    select (X + 1) from test where X <= to_date('2010-01-10','YYYY-MM-DD') 
  )
)
select * from test;

X
-------------------
2010-01-01 00:00:00

1 row selected

Преобразование даты в дату помогает, но где другие результаты?

Это становится еще лучше ...

Попробуйте это с другой датой начала:

with test(X) as
(
  select cast(to_date('2007-01-01','YYYY-MM-DD') as DATE) from dual
  union all (
    select (X + 1) from test where X <= to_date('2011-01-11','YYYY-MM-DD') 
  )
)
select * from test 
where rownum < 10; -- important!

X
-------------------
2007-01-01 00:00:00
2006-12-31 00:00:00
2006-12-30 00:00:00
2006-12-29 00:00:00
2006-12-28 00:00:00
2006-12-27 00:00:00
2006-12-26 00:00:00
2006-12-25 00:00:00
2006-12-24 00:00:00

9 rows selected

Считать в обратном порядке? Почему?

Обновление от 14 января 2014 г .: В качестве временного решения используйте CTE, начиная с даты окончания, и строите рекурсивное CTE в обратном порядке, например:

with test(X) as
(
  select cast(to_date('2011-01-20','YYYY-MM-DD') as DATE) as x from dual
  union all (
    select cast(X - 1 AS DATE) from test 
    where X > to_date('2011-01-01','YYYY-MM-DD') 
  )
)
select * from test 

Результаты:

|                              X |
|--------------------------------|
| January, 20 2011 00:00:00+0000 |
| January, 19 2011 00:00:00+0000 |
| January, 18 2011 00:00:00+0000 |
| January, 17 2011 00:00:00+0000 |
| January, 16 2011 00:00:00+0000 |
| January, 15 2011 00:00:00+0000 |
| January, 14 2011 00:00:00+0000 |
| January, 13 2011 00:00:00+0000 |
| January, 12 2011 00:00:00+0000 |
| January, 11 2011 00:00:00+0000 |
| January, 10 2011 00:00:00+0000 |
| January, 09 2011 00:00:00+0000 |
| January, 08 2011 00:00:00+0000 |
| January, 07 2011 00:00:00+0000 |
| January, 06 2011 00:00:00+0000 |
| January, 05 2011 00:00:00+0000 |
| January, 04 2011 00:00:00+0000 |
| January, 03 2011 00:00:00+0000 |
| January, 02 2011 00:00:00+0000 |
| January, 01 2011 00:00:00+0000 |

Тест проводился с:

Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
8
ответ дан 13 December 2019 в 22:04
поделиться

Я понятия не имею о несоответствии типов, но вот альтернативный метод достижения желаемого (который работает в 10gr2):

select base_time + numtodsinterval( 10*(level-1), 'Minute')
from (select trunc(systimestamp) base_time from dual)
connect by base_time + numtodsinterval( 10*(level-1), 'Minute') < systimestamp
0
ответ дан 13 December 2019 в 22:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: