Давайте разберем проблему.
Начните с двух совков. Это действительно упрощает вещи, если вы добавляете строку со значением NULL:
with flavors(flavor) as (
select 'vanilla' from dual union all
select 'strawberry' from dual union all
select 'chocolate' from dual union all
select null from dual
)
select * from flavors a
join flavors b on a.flavor <= nvl(b.flavor, a.flavor)
FLAVOR FLAVOR
chocolate -
chocolate chocolate
chocolate strawberry
chocolate vanilla
strawberry -
strawberry strawberry
strawberry vanilla
vanilla -
vanilla vanilla
Это работает из-за того, что Oracle обрабатывает NULL в сравнениях! Когда вы сравниваете NULL с чем угодно, даже с другим NULL, результат «неизвестен». Даже если вы сравниваете NULL с самим собой, результат никогда не бывает «верным». Итог: это условие гарантирует, что a.flavor не будет иметь значение NULL, что вам и нужно.
Теперь все, что нам нужно сделать, это добавить третий совок:
with flavors(flavor) as (
select 'vanilla' from dual union all
select 'strawberry' from dual union all
select 'chocolate' from dual union all
select null from dual
)
select * from flavors a
join flavors b on a.flavor <= nvl(b.flavor, a.flavor)
left join flavors c on b.flavor <= nvl(c.flavor, b.flavor);
Левое объединение гарантирует, что мы будем хранить строки там, где был только один совок.