Сравнение чего-либо со значением NULL приводит к НЕИЗВЕСТНОМУ, а не ЛОЖНОМУ.
По сути, это имеет тот же эффект, что и возвращение false, в том, что запрос будет возвращать только те строки, где сумма не равна нулю и больше 0, но вы должны быть осторожны, чтобы не предполагать, что когда сумма равна нулю, результат сравнение ложно
Например, при этом также не будут возвращаться пустые строки:
WHERE NOT(amount > 0)
amount > 0
НЕИЗВЕСТНО, а НЕ ЛОЖНО. Если бы это было ложно, то НЕ могло бы сделать это истинным
Вы могли бы себе представить, что NULL - это загрязняющий агент, который проходит весь путь через все логические условия и операции, к которым он прикасается, поворачивая их все НЕИЗВЕСТНО и затем «становится ложным» прямо в самый последний момент, потому что последний оценщик логического предиката требует ИСТИНА
В целом, вы можете считать НЕИЗВЕСТНЫЙ синонимом ПУСТОГО; UNKNOWN относительно ограничен логическими логиками c. В других контекстах, таких как математические операции с участием NULL, результат равен нулю (0 + NULL = NULL). Единственная операция, которая может работать со значением NULL и создавать логическое значение, - это amount IS [NOT] NULL
В соответствии с вашим обзором кода, если они собираются настаивать на общем покрытии, «необходимо объединить любое значение, которое может быть нулевым» Может показаться, что бизнес-правило состоит в том, что система не допускает значений NULL - в этом случае должно быть, что столбец сделан не NULL и заполнен только фактическими значениями. Передача любого значения через функцию, которая может изменить или не изменить его, ограничивает использование индексов и создает проблемы для планирования запросов. Можно надеяться, что умный оптимизатор сможет расширить / переписать ISNULL(amount, 0) > 0
до amount > 0 or (amount is null and 0>0)
, прежде чем упростить полностью удалить условие в скобках, но это не всегда так просто. Лучше не вводить дерьмо, во-первых, чем пожимание плечами и go «ну, в моем простом тестовом примере это, кажется, не делает вещи медленнее»
Применение общего правила без какой-либо мысли или оправдания может привести к очень плохо работающей системе. То, как вы будете передавать это людям, которые создают правила, может быть затруднительно с офисной политикой c, поскольку их подход неверен, но они вряд ли признают это или хотят, чтобы им говорили
Кроме того, вы можете почувствовать, что эквивалентный запрос лучше отражает представление о том, что вы пытаетесь сделать:
SELECT m.Name
FROM Members m
WHERE NOT EXISTS(
SELECT 1
FROM Fees f
WHERE m.Id = F.memberId and F.AmountDue > 0
)
Левый шаблон анти-объединения является моим любимым для всех видов, но я делаю чувствую, что это больше говорит само за себя - «все участники, которые не имеют связанных записей, где они должны деньги». NOT IN также делает это вполне читабельным, но его следует использовать с осторожностью, так как некоторые реализации базы данных могут быть довольно наивными:
SELECT m.Name
FROM Members m
WHERE NOT IN (
SELECT F.MemberId
FROM Fees f
WHERE F.AmountDue > 0
)
SQL сервер с большой вероятностью перепишет LEFT JOIN WHERE NULL / WHERE NOT EXISTS / WHERE NOT IN, поэтому они планируются и выполняются одинаково, но вы можете обнаружить, что в этом / dim представлении о подходе IN к следующему обзору кода не так много внимания:)