У меня есть вопрос относительно троичной логической логики, которая влияет на то, как реализовать сравнение между полиморфными сущностями в нашем поставщике LINQ.
В SQL, если вы присоединяете таблицу регионов с помощью внешнего ключа к стране:
SELECT * From Region r1, Region r2
WHERE r1.Country == r2.Country
(примечание: результаты одинаковы, используете ли вы JOIN или WHERE synthax)
Он вернет значения, где условие истинно, а не условие ложно или неизвестно (поскольку некоторые ключи имеют нулевое значение).Поэтому, если мы отменим условие:
SELECT * From Region r1, Region r2
WHERE r1.Country != r2.Country
Мы получим значения, где условие истинно (теперь это разные ключи), и мы пропустим те, которые имеют одинаковые ключи, или те, которые имеют какое-то нулевое значение, потому чтоусловие возврата неизвестно снова.Даже если мы напишем это так:
SELECT * From Region r1, Region r2
WHERE not(r1.Country == r2.Country)
Неизвестное будет распространено, поэтому для этого простого условия никогда не появятся нули.Все идет нормально.
Теперь давайте представим, что у Региона может быть Страна (для небольших европейских стран) или Государство (для США, России, Китая ...).Если у региона есть государство, у него будет страна ноль, и наоборот.
Как мы можем присоединиться к паре [Страна, Штат], чтобы она имела те же свойства, что и раньше ?:
SELECT * From Region r1, Region r2
WHERE r1.Country == r2.Country OR r1.State == r2.State
Это выражение вернет true, если оно присоединится, иначе неизвестно.Нам бы хотелось, чтобы он возвращал неизвестное только в том случае, если все поля пустые, в противном случае, если мы отрицаем:
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?
- Истина, когда совпадает
- Ложь, когда не совпадает
- Неизвестно, если какой-либо операнд равен нулю.