Упражнение 60 (подсказки и решения)
В решении 2.3.1 используется полное внешнее соединение (FULL JOIN) подзапросов, чтобы учесть возможные варианты, когда в результате выполнения этих подзапросов для какого-нибудь пункта приема либо сумма прихода, либо сумма расхода будет NULL-значением (другими словами, не было расхода и/или прихода). Если, скажем, полученный приход составляет 1000, а расход — 800, то будут учтены все возможные варианты:
Приход | Расход |
---|---|
1000 | 800 |
NULL | 800 |
1000 | NULL |
Варианта NULL NULL быть не может, так как это бы означало, что пункта приема просто не существовало (на данный момент времени).
В предложении SELECT используется конструкция, которая должна заменить NULL нулем в выражении вычисления остатка. Логика совершенно правильная, однако конструкция применена неверно:
CASE inc
WHEN NULL
THEN 0
ELSE inc
END
Ошибка заключается в том, что здесь фактически задействована простая операция сравнения с NULL-значением, а именно,
CASE
WHEN inc = NULL
THEN 0
ELSE inc
END
Сравнение же с NULL-значением всегда дает UNKNOWN. Поэтому условие WHEN не выполняется, в результате чего выполняется ветвь ELSE, всегда возвращая значение inc, даже в том случае, когда inc есть NULL.