Разница между NVL и OR в SQL oracle - PullRequest
1 голос
/ 05 марта 2020

Эй, ребята, кто-нибудь может объяснить мне разницу между NVL () и ИЛИ в следующем запросе:

Select 
count(*)                         
from SHIPMENTSTATUS  
WHERE insert_date  between  trunc(sysdate) -2 and  trunc(sysdate) -1  or  update_date BETWEEN trunc(sysdate) -2 and  trunc(sysdate) -1

Количество строк: 44937

и

Select 
count(*)
from SHIPMENTSTATUS  
where NVL(UPDATE_DATE, INSERT_DATE) between  trunc(sysdate) -2 and  trunc(sysdate) -1

Количество строк: 44782

Почему мы имеем эту разницу: 155 строк? Я построил несколько запросов на основе nvl и заметил эту проблему и собираюсь переключиться на OR, но я действительно хочу знать, почему это такая разница. Спасибо за объяснение

Ответы [ 2 ]

3 голосов
/ 05 марта 2020

Когда UPDATE_DATE не равно нулю NVL(UDATE_DATE, INSERT_DATE) увеличивается до UPDATE_DATE и INSERT_DATE не будет использоваться вообще. Записи с INSERT_DATE в диапазоне, но ненулевым UPDATE_DATE за пределами этого диапазона будут включены в первый запрос, но исключены во втором.

0 голосов
/ 05 марта 2020

Первое условное выражение проверяет, находится ли один из двух столбцов в целевом диапазоне дат.

Второе выражение проверяет второй столбец , только если первый столбец null. Таким образом, если первый столбец не null и не находится в диапазоне, условие не выполняется. Это более ограничительно.

Что-то эквивалентное:

nvl(update_date, insert_date) 
    between  trunc(sysdate) - 2 and  trunc(sysdate) - 1

Было бы:

update_date between  trunc(sysdate) - 2 and trunc(sysdate) - 1  
or ( 
    update_date is null 
    and insert_dateBETWEEN trunc(sysdate) - 2 and  trunc(sysdate) - 1
)
...