Ошибка SQL в управлении выбором для поиска последовательного шестнадцатеричного числа с отверстием после фильтра после объединения - PullRequest
0 голосов
/ 28 августа 2018

Я хочу вставить шестнадцатеричное последовательное число в поле ad_code char(5) и обработать / заполнить его отверстия.

Для ускорения запроса из исходной таблицы table1

Column name          Type                                    Nulls
ad_code              char(5)                                 yes
ad_value             smallint                                yes

У меня есть вид:

create view v_table1 (vacr_ad_code) as select
ad_code
from table1 where (NVL(ad_code, ' ') != ' ');

Затем я попытался использовать этот запрос для получения нового значения или, в конечном итоге, дыры:

select HEX('0x'||NVL( l.vacr_ad_code, '0'))::INT + 1
from v_table1 as l
left outer join v_table1 as r on
HEX('0x'||NVL( l.vacr_ad_code, '0'))::INT + 1 =
HEX('0x'||NVL( r.vacr_ad_code, '0'))::INT
where
r.vacr_ad_code is null ORDER BY 1 ASC;

но со следующими значениями в БД

vacr_ad_code    
1
2
4

вместо получения 3 и 5, как я ожидал, у меня есть:

(expression) 
        2
        3
        5

Почему номер 2 присутствует? Где я не прав?

Обновление: если я изменю запрос таким образом:

select HEX('0x'||NVL( l.vacr_ad_code, '0'))::INT + 1,
HEX('0x'||NVL( r.vacr_ad_code, '0'))::INT
from v_table1 as l
left outer join v_table1 as r on
HEX('0x'||NVL( l.vacr_ad_code, '0'))::INT + 1 =
HEX('0x'||NVL( r.vacr_ad_code, '0'))::INT
ORDER BY 1 ASC;

Я получаю:

(expression) (expression)  
        2     2
        3     null
        5     null

Если я добавлю фильтр: where r.vacr_ad_code is null Я получу

(expression) (expression)  
        2     null
        3     null
        5     null

Кажется, что фильтр пост-соединения изменяет результат внешнего соединения

1 Ответ

0 голосов
/ 28 августа 2018

Во-первых, почему ваш взгляд просто не делает:

create view v_table1 (vacr_ad_code) as
    select ad_code
    from table1
    where ad_code is not null;

Я не вижу, как это улучшило бы скорость любого запроса.

Если вы хотите, чтобы «следующие» числа не существовали, я сначала попробую:

select cast(t.ad_code as int) + 1
from table1 t
where not exists (select 1
                  from table1 t1
                  where cast(t1.ad_code as int) = cast(t.ad_code as int) + 1
                 );

Я бы посоветовал вам хранить ad_code как число, потому что именно так вы используете значение.

...