1. SQL / Говнокод #8665

    −126

    1. 1
    2. 2
    3. 3
    AND (type = 2 OR type = 5 AND (type <> 3 OR type <> 20))
    
    Очередной перл предшественника :)

    Запостил: labutinpa, 29 Ноября 2011

    Комментарии (30) RSS

    • мэджик намберс...
      Ответить
    • `(type <> 3 OR type <> 20)` всегда тру. или я чего-то не улавливаю?
      Ответить
      • Вот и я некоторое время тупил, глядя на это, думая, что я чего-то не улавливаю.
        Ответить
        • значит тупили в двойне. перед тем как постить коммент, я перловый однострочник набросал и удостоверился, что да, всегда тру ;)

          думание это медленно. просто написать и запустить часто быстрее.
          Ответить
          • Тут ещё кстати, всё просто, я даже код писать не стал. Возможно, вот так косяк очевиднее:
            NOT (type=3 AND type=20)
            Ответить
            • Да тут реально всё просто и без правила Де Моргана.
              Ответить
      • если type is null, то по тернарной логике получим
        (type <> 3 OR type <> 20) = UNKNOWN
        Ответить
        • плохо у тебя с логикой. даже с бинарной.
          (null <> 3) = true
          (null <> 20) = true
          Ответить
          • пиздец...
            запасся попкорном
            Ответить
          • U cannot into nullz.
            Null - специальное значение, которое ничему не равно и не равно.
            null + 1 = null
            null > 1 = null
            и в том же духе.
            Ответить
            • > U cannot into nullz
              But he can into lullz
              Ответить
            • ога, плюс расширения для AND, OR, NOT...
              http://en.wikipedia.org/wiki/Three-valued_logic#Kleene_logic
              Ответить
            • >которое ничему не равно и не равно.
              ха-ха. суровая логика. чую спор зайдет в тупик, как обычно. и не равно.

              >null + 1 = null
              да, но тут речь не о сложении с null, а о сравнении (равенстве/неравенстве).

              И если Null - специальное значение, которое ничему не равно.
              То логично предположить, что null не равно 3.
              Ответить
              • нет шансов, что незнающих про NULL проймет указание на аналогичное поведение c NaN
                Ответить
              • > суровая логика.
                И не не равно, само собой. Одно отрицание выпустил. Не придирайся.

                Зачем спорить, давай поставим эксперимент.
                Есть под рукой mysql? Достаточно выполнить два запроса и подумать.
                1)
                select 'Y' from sometable where null <> 3

                2)
                select 'Y' from sometable where (null <> 3) is null

                (Для баз типа DB2 null нужно заменить на nullif(-1,-1))
                Выводы можно сделать самостоятельно.
                Ответить
                • >Одно отрицание выпустил. Не придирайся.
                  Ок. Принято.
                  >давай поставим эксперимент.
                  Здравая мысль.

                  В мускуле для правильных результатов нужно юзать <=>.

                  В T-SQL работает и так
                  (null==null) = true .
                  и (Null<>3) = true

                  В Оракле (null=null) будет вроде null. Аналогично MySql.

                  >И не не равно, само собой.
                  Понятно, о чем речь. Всё зависит от используемых таблиц истинности в том или ином случае.
                  Я, лично, не считаю что логика поведения Null должна быть аналогична NaN.
                  Это неудобно и приводит к таким вот косякам (null<> 3 OR null <> 20) = Null.
                  Ответить
                  • > В T-SQL работает и так
                    Не сталкивался. Знаю только, что в mysql, db2, postgres и firebird null не равен даже самому себе.
                    Есть простое правило. Любое действие с null'ом, кроме is null на выходе даёт null. И у этого есть смысл.
                    Если аргумент не ожидается null, все условия будут работать правильно. Если ожидается, то потребно использовать is null или coalesce.
                    Ответить
                    • >Любое действие с null'ом, кроме is null на выходе даёт null
                      В этом есть своя логика. Но это неудобно.
                      К тому же оно только на словах звучит так просто "любое кром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, например
                        К сожалению, в сортах mysql не разбираюсь. Но в какой-то не шибко новой DB2 было именно так, как я описывал.
                        Не знаю, что там насчёт удобства. Мне было удобно считать null именно так. Не представляю совсем, кому может понадобиться сравнивать их меж собой или с другими значениями.
                        Ответить
    • кстати, сильно ли это бьет по производительности?
      скиньте план запроса
      Ответить
      • По-идее, совсем не влияет. Я даже проверил. Не влияет.
        Однако влияет на мозг. Я долго (тупил) искал подвох в этом условии, чтобы ничего не испортить при оптимизации.
        Ответить
    • type = 5 AND (type <> 3 OR type <> 20)

      вот это конечно полная жесть. нельзя так издеваться над людьми
      Ответить
    • это не перл, это скул!
      Ответить
    • это проблемы с логикой
      Ответить
    • какая глубокая идея
      Ответить
    • Не всем булева логика по-плечу.
      Ответить
    • Попробовал натравить на all_objects (вместо type фильтровал по object_id)
      В плане получил 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))
      Ответить
    • От кода кровоточат глаза.    +1
      Ответить
    • показать все, что скрытоvanished
      Ответить

    Добавить комментарий