- 1
- 2
- 3
AND (type = 2 OR type = 5 AND (type <> 3 OR type <> 20))
Очередной перл предшественника :)
Нашли или выдавили из себя код, который нельзя назвать нормальным, на который без улыбки не взглянешь? Не торопитесь его удалять или рефакторить, — запостите его на говнокод.ру, посмеёмся вместе!
−126
AND (type = 2 OR type = 5 AND (type <> 3 OR type <> 20))
Очередной перл предшественника :)
думание это медленно. просто написать и запустить часто быстрее.
(type <> 3 OR type <> 20) = UNKNOWN
(null <> 3) = true
(null <> 20) = true
запасся попкорном
Null - специальное значение, которое ничему не равно и не равно.
null + 1 = null
null > 1 = null
и в том же духе.
But he can into lullz
http://en.wikipedia.org/wiki/Three-valued_logic#Kleene_logic
ха-ха. суровая логика. чую спор зайдет в тупик, как обычно. и не равно.
>null + 1 = null
да, но тут речь не о сложении с null, а о сравнении (равенстве/неравенстве).
И если Null - специальное значение, которое ничему не равно.
То логично предположить, что null не равно 3.
И не не равно, само собой. Одно отрицание выпустил. Не придирайся.
Зачем спорить, давай поставим эксперимент.
Есть под рукой mysql? Достаточно выполнить два запроса и подумать.
1)
2)
(Для баз типа DB2 null нужно заменить на nullif(-1,-1))
Выводы можно сделать самостоятельно.
Ок. Принято.
>давай поставим эксперимент.
Здравая мысль.
В мускуле для правильных результатов нужно юзать <=>.
В T-SQL работает и так
В Оракле (null=null) будет вроде null. Аналогично MySql.
>И не не равно, само собой.
Понятно, о чем речь. Всё зависит от используемых таблиц истинности в том или ином случае.
Я, лично, не считаю что логика поведения Null должна быть аналогична NaN.
Это неудобно и приводит к таким вот косякам (null<> 3 OR null <> 20) = Null.
Не сталкивался. Знаю только, что в mysql, db2, postgres и firebird null не равен даже самому себе.
Есть простое правило. Любое действие с null'ом, кроме is null на выходе даёт null. И у этого есть смысл.
Если аргумент не ожидается null, все условия будут работать правильно. Если ожидается, то потребно использовать is null или coalesce.
В этом есть своя логика. Но это неудобно.
К тому же оно только на словах звучит так просто "любое кромe is (not) null",
а на деле не любое - вышеупомянутый <=> в MySql, например.
Насчет T-SQL, там всё чуть сложнее, но как я уже сказал зависит от выбранных правил сравнения
http://msdn.microsoft.com/en-us/library/aa196339(v=sql.80).aspx
When SET ANSI_NULLS is ON, a comparison in which one or more of the expressions is NULL does not yield either TRUE or FALSE; it yields UNKNOWN. This is because a value that is unknown cannot be compared logically against any other value. This occurs if either an expression is compared to the literal NULL, or if two expressions are compared and one of them evaluates to NULL.
Transact-SQL supports an extension that allows for the comparison operators to return TRUE or FALSE when comparing against null values. Сomparisons such as ColumnA = NULL return TRUE when ColumnA contains a null value and FALSE when ColumnA contains some value besides NULL. Also, a comparison of two expressions that have both evaluated to null values yields TRUE.
Regardless of the ANSI_NULLS setting, Null values are always considered equal for the purposes of the ORDER BY, GROUP BY, and DISTINCT keywords. Also, a unique index or UNIQUE constraint that allows NULL can contain only one row with a NULL key value. A subsequent row with NULL is rejected. A primary key cannot have NULL in any column that is part of the key.
К сожалению, в сортах mysql не разбираюсь. Но в какой-то не шибко новой DB2 было именно так, как я описывал.
Не знаю, что там насчёт удобства. Мне было удобно считать null именно так. Не представляю совсем, кому может понадобиться сравнивать их меж собой или с другими значениями.
скиньте план запроса
Однако влияет на мозг. Я долго (тупил) искал подвох в этом условии, чтобы ничего не испортить при оптимизации.
вот это конечно полная жесть. нельзя так издеваться над людьми
В плане получил 2 съюнионенных запроса, отличающихся следующими предикатами доступа и фильтрации:
7 - access("O"."OBJ#"=5)
filter("O"."OBJ#"<>3 OR "O"."OBJ#"<>20)
и
73 - access("O"."OBJ#"=2)
filter(LNNVL("O"."OBJ#"=5) OR LNNVL("O"."OBJ#"<>3) AND
LNNVL("O"."OBJ#"<>20))