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

    −155

    1. 1
    CASE WHEN ((b.k_vts_pre = null) OR (b.k_vts_goz_pre = null) OR (b.k_vts_relative_pre = null)) THEN null ELSE (b.k_vts_pre + b.k_vts_goz_pre + b.k_vts_relative_pre)/3 END

    Один наш сотрудник проявил старание, достойное лучшего применения. В PostgreSQL можно так сравнивать с NULL, если настройка transform_null_equals=on. Но, во-первых, она у нас, как и по умолчанию, off, а во-вторых, зачем вообще?

    Запостил: torbasow, 09 Сентября 2013

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

    • > а во-вторых, зачем вообще
      Закат солнца руками :) Видимо автор не знал, что нулл отравляет почти все выражения, в которые он входит.
      Ответить
    • Не люблю однострочную портянку.
      CASE WHEN ((b.k_vts_pre = null)
      		OR (b.k_vts_goz_pre = null) 
      		OR (b.k_vts_relative_pre = null)) 
      	THEN null 
      	ELSE (b.k_vts_pre + b.k_vts_goz_pre + b.k_vts_relative_pre)/3 
      END


      Сотрудник бОльшую часть времени работает с императивным языком, верно?
      Ответить
      • > бОльшую часть времени работает с императивным языком
        Вы так говорите, как-будто в императивных языках такие гигантские одностроки это что-то хорошее ;)
        Ответить
        • Не... Я клонил к тому, что в императивных языках чаще проверяют явно объекты на пустоту, а не запоминают дефолтное поведение компилятора.
          Ответить
      • Я тоже первым делом сделал форматирование.
        Ответить
    • Причудливый механизм, сравнение через "=" режет глаз, как-то ненатурально.
      Ответить
      • Добро пожаловать в пасцаль.
        Ответить
      • > Причудливый механизм
        В отличие от мускуля, в постгресе вся эта срань причудливость хотя бы по дефолту отключена...

        Хотя я, на их месте, вообще не стал бы запиливать эту фичу. is null и is not null вполне достаточно.
        Ответить
        • как по мне, is null/is not null говно.

          у нас тут давеча где-то пол года назад была история с оракаклом. куче крутых бородатых дядек и матёрых теток, которые 10+ лет исключительно оракл хакают, понадобилось пара месяцев что бы "увидеть" написаный новичком `= null` вместо `is null`. но зато потом как рассмотрели, ржали ходили пол дня, остановится не могли. потому что важный баг, а кода кот наплакал и его весь почти все уже наизусть выучили. но все равно тормозили 2 месяца.

          если даже ДБ девелоперы тормозят, которые ничего кроме (PL/)SQL не видят, то это хороший индикатор что это говно, а не фича. в конце концов, а зачем еще может быть нужно сравнение с магичской константой нулл?
          Ответить
          • вот так вот разреши делать = null, потом начнутся сопли, что фича то говно - с чиселками джойница, а с нуллами то нет
            или теперь будет да?
            Ответить
            • а как это по нуллам джоинить? а можно ли вообще? смысл? ни разу не пробовал.

              но так как правило джоины все равно идут по индексам, то там уже почти всегда прописан not null в любом слючае. практической проблемы не вижу.
              Ответить
              • а null больше десяти?
                Ответить
                • false. как было так и остается false'ом.

                  или в чем вопрос/подкол?
                  Ответить
                  • если false, то значит можно взять обратное условие и получить true
                    select * from table where col1 <= 10
                    Ответить
                    • да. но по моему ты излишне экстраполируешь мои слова. здесь в контексте речь идет о `= null`. остальным сравнениям менятся не надо - они уже работают как и ожидается.
                      Ответить
                  • > false
                    a = null это не false. Это, емнип, ахуйбыегознал, для краткости обозначаемый NULL'ом, и трактуемый условными операторами как ложь :)
                    Ответить
                    • Там немного не так:
                      a = null => false
                      a <> null => false
                      в итоге выходит, что a ахуйбыегозналкаксравнить null (вот тут и выходит на сцену IS/IS NOT)
                      Ответить
                      • Ну не знаю насчет стандарта, я этот момент там не читал, но в постгресе получается вот так:
                        null = null => null
                        null <> null => null
                        null = 1 => null
                        null <> 1 => null
                        1 <> 2 => true
                        1 = 2 => false
                        Может быть это только постгресовая фишка. Но выглядит вполне логично - null отравляет любые операторы (включая сравнения и логику), превращаяя их результат в null. Т.е. not (a = null) это не true, как могло бы показаться, а тоже null.
                        Ответить
                        • Из http://en.wikipedia.org/wiki/Null_(SQL)

                          "The actual typing of Unknown (distinct or not from NULL itself) varies between SQL implementations"

                          Ну т.е. таки да, зависит от СУБД.
                          Ответить
                          • Т.е. все эти конструкции возвращают Unknown, который на многих реализациях обозначен NULL'ом... Ясно.
                            Ответить
                      • > a = null => false
                        > a <> null => false
                        А not (a = null) и not (a <> null)? :)
                        Ответить
                      • Все, мой моск окончательно убит этой троичной логикой постгреса:
                        true and null => null
                        true and false => false
                        false and null => false
                        null and false => false
                        
                        null or false => null
                        false or null => null
                        true or null => true
                        UPD: все ок, логика абсолютно корректна, если считать NULL как хуйбызналчемуравно.
                        Ответить
                      • null = null => ?
                        null != null => ?
                        Ответить
                      • Да, тут был не прав. Сбил пример:
                        declare @a int
                        if (@a = null) print '1' 
                        	else if (@a <> null) print '2' 
                        		else print '3'

                        Выхлоп будет 3
                        Ответить
          • А потом кому-то покажется, что SELECT NULL IN (1, NULL) должно давать TRUE, и кончим мы тем, что NULL будет всегда равен NULL, и прощай, стандарт SQL.
            UPD: Упс! Вернулся к разбору того же запроса, и обнаружил, что тому же сотруднику и правда так уже показалось.
            Ответить
            • Небольшой вброс.

              Да там и так уже нелогичностей хватает... Вот берем к примеру постгрес с дефолтными настройками, и вот такую табличку:
              a    | b
              -----+-----
              NULL | 1
              NULL | 2
              1    | 2
              2    | 3
              Выполняем запрос
              select a, sum(b) from test group by a
              и получаем... сгруппированные NULL'ы. Т.е. все-таки NULL = NULL? :)

              Теперь выполняем запрос
              select sum(a), b from test group by b
              и получем... что сумма NULL и 1 это 1. Т.е. все-таки NULL это 0? :)
              Ответить
              • О группировке: «The standard is clear about each of these things separately. It absolutely says that nulls should be grouped together, and it absolutely says that the comparison operator should not. It's true that these things are not consistent, but for each operation, the standard is quite clear on how it should be done» (http://www.postgresql.org/message-id/l03130307b3688a1e21f0@%5B147.233.159.109 %5D).
                Что касается суммы, то NULL’ы не принимаются за ноль, а просто исключаются из суммирования. Да, эффект тот же, и да, я полагаю это непоследовательным.
                Ответить
                • > просто исключаются из суммирования
                  А сумма пустого множества какого-то хрена равна NULL, а не 0, и приходится дописывать всякие nvl и coalesce. Для AVG от пустого множества NULL вполне логичен, но SUM то за что испортили? Авторы стандарта не признают математику :(
                  Ответить
                  • выбрать из таблицы1 все строки, в которых значение в колонке1 > сумма в колонке2 в таблице2 с нужным фильтром
                    если бы sum(null, null, ...) была бы 0, то результат получится совсем другой
                    Ответить
                    • > то результат получится совсем другой
                      Все строки с положительным значением колонки1 вместо пустого множества... Ну да, резонно.
                      Ответить
            • > и прощай, стандарт SQL.

              во-первых: бля, тоже мне нашел что стандартом называть.

              во-вторых: я ни разу не предлагал менять что либо кроме как `= null` и `<> null` сделать аналогами `is null` и `is not null`.
              Ответить
              • >>во-первых: бля, тоже мне нашел что стандартом называть.
                что не так с ISO/IEC 9075?
                Ответить
                • написать приложение которое использует только стандартные фичи - в принципе не возможно. там просто фич не хватает. я как минимум три раза в прошлом пытался. либо производительность в жопу, либо какие побочные эффекты как палки в колёса.

                  в добавок, есть такая достаточно распростаннёная парадигма, что если уже выложил денег за Оракакал/DB2/Sybase/этц, то грешно не пользоватся специальными фичами.

                  ЗЫ глубже не спрашивай - уже лет 15 не колупал и все забыл.
                  Ответить
                  • Я согласен с тем что ничего сложнее гостевой книги нельзя написать не используя специфичные функции субд (потому мне всегда смешно когда говорят что "базу данных можно сменить в любой момент"), однако если уж стандарт что-то определяет то лучше его соблюдать: это упростит понимание кода во всяком-то случае
                    Ответить
                    • показать все, что скрытоvanished
                      Ответить
                      • >> со скольки записей в базе заканчивается "гостевая книга"
                        Ты считаешь что сложность проекта обусловлена количеством записей в базе?
                        Типа если у тебя 10 записей то можно MySQL, а если 2000 то надо уже Oracle? Ты правда так думаешь?
                        Ответить
                        • А если 4000000 -- то какой-нибудь nosql.
                          Ответить
                          • Между прочим я такие диалоги как-то наблюдал

                            --А MySQL 10 000 записей выдержит?
                            --Выдержит
                            --А Postgres?
                            --Тоже
                            --А в чем тогда разница?
                            --В названии
                            Ответить
        • в мускуле если память не изменяет не только отключена но и нет возможности включить.
          Ответить
          • > память не изменяет
            Не изменяет :) Зато там другой гадости полно. Типа or'а в виде ||.
            Ответить
            • и в пышечке так и даже сишечке. Что плохого ?
              Ответить
              • в том, что все привыкли, что || в sql - это конкатенация строк
                Ответить
                • Кому может понадобиться конкатенация? Логические операции куда важнее.
                  Ответить
                  • для логических операций есть or
                    для следования стандартам есть стандарты
                    для всего остального есть мастеркард
                    Ответить
                  • В XSLT, очевидно, так и решили.
                    Ответить
      • Или ты имел в виду сравнение с null через = ?
        Ответить
        • Походу именно его. Все остальное же в SQL именно через = сравнивается.
          Ответить
      • С точки зрения сишколяди, забывшей человеческий язык, безусловно так.
        Ответить
        • Кстати а откуда пошла фраза: С точки зрения X безусловно так.
          Где Х - негативная характеристика обладателя оной точки зрения.Гоблача не предлагать.
          Ответить
          • От ст.оу. Гоблина, если не путаю.
            У него обычно "С точки зрения малолетнего долбоеба - безусловно".
            Ответить
            • Что-то мне подсказывает что фраза старше гоблина, просто он зафорсилввёл её в массовый рунетный обиход. Я в спойлере потому и написал.
              Ответить
              • Ваш спойлер слишком тонок, я его не увидел =D
                Ответить
        • > сишколяди
          сишколеди
          Ответить
          • си-школяди
            Ответить
            • си-школ-ляди
              Ответить
              • Кстати, а куда делся Царь? Он же обещал в сентябре тут всё засрать. Уроков много назадавали?
                Вот уж средина близится,
                А супервафела всё нет...
                Ответить
          • эээээй! Сишколеди!
            Оп! Оп! Оп! Оп! Оп!
            Процедурный стаил
            Ответить
        • Я имел в виду сравнение с null'ом, разумеется, но ты на всякий случай тоже хуй.

          P.S. Не хочу устраивать священную войну на тему, почему надо ставить двоеточие и что значит символ "меньшебольше".
          Ответить
    • Поэтому я за "MySQL".
      Ответить
    • Мне казалось что в SQL NULL не равен ничему, даже самому себе (как NaN у сеьмсот пятисят читвретого питуха).
      Проверять надо через
      IS NULL

      Причем во всех субд
      Ответить

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