Мне интересно ваше решение, что запрос с рекурсивным общим табличным выражением (RCTE) является "ненормальным".IBM называет его «оператором выбора» и считает его нормальным.Если это какой-то образовательный вопрос, и вы не хотите использовать RCTE по какой-либо причине, рассмотрите следующий пример.
select s + (3*(x.i-1)) month start, s + (3*x.i) month - 1 day end
from table(values (date('2011-01-01'), date('2012-01-01'))) d(s, e)
, xmltable('for $id in (1 to $e) return <i>{number($id)}</i>'
passing ((year(e)-year(s))*12 + (month(e)-month(s)))/3 as "e"
columns i int path '.'
) x;
START END
---------- ----------
2011-01-01 2011-03-31
2011-04-01 2011-06-30
2011-07-01 2011-09-30
2011-10-01 2011-12-31
;
Это немного сложно, так как вы должны передать желаемое количество строкчтобы вернуться к табличной функции xmltable, которая возвращает один столбец со значениями от 1 до N. Другими словами, вы должны вычислить желаемое количество 3-месячных интервалов и передать его функции.
(R) CTE можетне использоваться в операторах UPDATE / DELETE, где вы можете использовать только так называемые операторы полной выборки (они не допускают CTE).Если вам действительно нужно использовать CTE для UPDATE / DELETE, как в этом случае, вы можете выполнить одно из следующих действий:
Если вы способны вычислить временный набор результатов для всего оператора delete / update, вы можете сделатьчто-то вроде этого (я не использую здесь RCTE для простоты, но только для простого CTE):
with a (id) as (values 1)
select count(1)
from old table(
delete from test t
where exists (select 1 from a where a.id=t.id)
);
Если вы НЕ МОЖЕТЕ вычислить временный набор результатов для всего оператора delete / update, вы можетесоздайте табличную / скалярную функцию с соответствующими параметрами, где вы сможете использовать свой RCTE.Впоследствии эта функция может использоваться во внешнем выражении.