У меня есть вопрос относительно троичной логической логики, которая влияет на то, как реализовать сравнение между полиморфными сущностями в нашем поставщике LINQ.
В SQL, если вы присоединитесь к таблице Region с помощью внешнего ключа Country :
SELECT * From Region r1, Region r2
WHERE r1.Country == r2.Country
(примечание: результаты идентичны независимо от того, используете ли вы синтаксис JOIN или WHERE)
Он вернет значения, в которых условие истинно, а не тогда, когда условие ложно или неизвестно (поскольку некоторые ключи равны нулю). Итак, если мы отрицаем условие:
SELECT * From Region r1, Region r2
WHERE r1.Country != r2.Country
Мы получаем значения, где условие истинно (теперь разные ключи), и мы пропустим те, которые имеют одинаковые ключи, или те, которые имеют какое-то нулевое значение, потому что условие снова возвращает неизвестное. Даже если мы напишем так:
SELECT * From Region r1, Region r2
WHERE not(r1.Country == r2.Country)
Неизвестное будет распространяться, поэтому для этого простого условия никогда не появятся нули. Все идет нормально.
Теперь давайте представим, что в Регионе может быть Страна (для небольших европейских стран) или Штат (для США, России, Китая...). Если у региона есть штат, у него будет значение Country null, и наоборот.
Как мы можем объединить пару [Страна, Штат], чтобы она имела те же свойства, что и раньше?:
SELECT * From Region r1, Region r2
WHERE r1.Country == r2.Country OR r1.State == r2.State
Это выражение вернет значение true, если оно соединяется, в противном случае — неизвестное. Мы хотели бы, чтобы он возвращал unknown только в том случае, если все поля равны нулю, иначе, если мы отрицаем:
SELECT * From Region r1, Region r2
WHERE not(r1.Country == r2.Country OR r1.State == r2.State)
Он не возвращает строк!. Если мы попробуем более запутанное выражение:
SELECT * From Region r1, Region r2
WHERE (r1.Country == r2.Country AND r1.Country IS NOT NULL AND r2.Country IS NOT NULL)
OR (r1.State == r2.State AND r1.State IS NOT NULL AND r2.State IS NOT NULL)
Затем он вернет true, если пара совпадает, false в противном случае и никогда ничего. Затем, если мы отрицаем, он вернет значения, в которых все строки равны нулю, что ведет себя иначе, чем в первом примере.
Итак, какое выражение для сравнения этой пары будет вести себя как равенство SQL?
- Истина при совпадении
- False, если не соответствует
- Неизвестно, когда какой-либо операнд имеет значение null.