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

    −863

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    select top 1 v.Id
       from dbo.Verification v
       where v.ApplicationId = a.Id
        and v.ResultId = 'D69E0B3A-C5CA-42D0-A8CA-FA7FF63BC414'
        and not exists (
         select 1 from Verification vo
         where vo.ApplicationId = v.ApplicationId
          and vo.ResultId = v.ResultId
          and vo.Id != v.Id
          and vo.Position > v.Position
        )

    MS SQL. Видимо, автору не рассказали об order by

    Запостил: alex123098, 21 Октября 2014

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

    • показать все, что скрытоХм... Алекс...
      Нераздобанная жопа?
      Ответить
    • Ради "пока нечего делать", решил проверить равнозначны ли запросы так и ордер бай

      if object_id('tempdb..#tabl') is not null drop table #table
      create table #table
      (A varchar(20),
      B int)

      insert into #table (A,B)
      VALUES ('Паша', 5);
      insert into #table (A,B)
      VALUES ('Cаша', 5);
      insert into #table (A,B)
      VALUES ('Даша', 5);
      insert into #table (A,B)
      VALUES ('Маша', 5);

      select top 1 A from #table
      ORDER BY B DESC

      select top 1 t.A from #table as t
      WHERE not exists (
      select top 1 t1.A from #table as t1
      WHERE t1.B > t.B
      )

      У меня вывелось (проверял на 2003-ем):
      Саша
      Паша

      В чем прикол?
      Ответить
      • Во втором случае запрос выведет первую же запись, которая удовлетворяет условию, что записи с бо́льшим значением второго поля отсутствуют.

        А в первом случае СУБД сначала сортирует всю таблицу. Я догадываюсь, что сортировать массив одинаковых значений не полезнее, чем носить воду в решете, но тупая машина может этого не знать и перемешать таблицу. Потому и выводит не первую строку, а случайную.
        Ответить
        • В том то и дело, что кажется order by не мешает таблицу, при выводе всей (без top 1) вывелась вся таблица точно также как вносил.
          И еще одна фигня, при top 4 он как раз вывел таблицу в обратном порядке
          Ответить
          • > вся таблица точно также как вносил
            > при top 4 он как раз вывел таблицу в обратном порядке
            Если нет order by - СУБД имеет полное право вывести записи в любом порядке. К сожалению, зачастую, она выводит их в порядке вставки, и люди считают, что order by лишний.
            Ответить
            • P.S. А если order by есть, и все поля, перечисленные в нем совпали - то записи тоже выводятся в любом порядке.

              Так что либо добавляй еще колонок в order, либо получай недетерминированный выхлоп.
              Ответить
              • > и все поля, перечисленные в нем совпали
                простите, совпали с чем?
                Ответить
                • Кажись, догнал. Значения в полях одинаковые хотя бы в границах одного поля.
                  Ответить
                • > простите, совпали с чем?
                  Я криво выразился, наверное... Примерно так:
                  select id, name, mark from some order by mark;
                  
                  1|Маша|4
                  5|Саша|5
                  3|Света|5
                  8|Дима|5
                  Все пятёрки гарантированно идут после четверок. Но вот порядок записей среди этой группы пятёрок не определен, если еще чего-нибудь не добавить в order. Вот это я имел в виду.
                  Ответить
            • Зачастую СУБД руководствуется кластерным индексом, так как записи по нему упорядочиваются в файле на диске. А вообще, многое зависит от плана запроса, который зависит от статистики, индексов и прочего.
              Ответить
              • > руководствуется кластерным индексом
                Если СУБД в него умеет и его создали...

                > многое зависит от плана запроса
                Ну вот и я о том же. Нет ордера - никаких гарантий.
                Ответить
          • У баз данных бывает скрытая колонка, значение которой нельзя получить стандартными средствами. Например в MySQL так делает движок InnoDB, добавляя к таблице невидимую колонку с уникальным индексом. Некоторые операции выбирают строки в физическом порядке расположения, а некоторые по этому самому индексу.
            Ответить
            • мне кажется, это почти повсеместно - иметь физический айди записи
              иначе ни ACID, ни роллбек не сделать
              Ответить
            • У mssql ее нет (по крайней мере раньше не было, сейчас не знаю). Для этих целей может служить поле с типом timestamp(это не время), которая хранит версию строки, но ее надо самому добавлять, если конечно она нужна. Мне вот например не так потребовалась. Была задача, нужно было в очередь обработки помещать записи, и пользователи моли по 100500 раз инициировать процесс. Поэтому, в процедуру обработчик я передавал эту версию, ставил задержку на пару секунд, и проверял, чтобы обработка происходила только, если версия строки в таблице совпадает с той, что была передана в запросе. Благодаря этому, отрабатывал только последний запрос на обработку.
              Ответить
              • оно есть в любой субд, даже ms sql
                т.к. тебе так или иначе необходимо знать физический адрес записи - в каком файле/блоке/по какому смещению он лежит - хотя бы для того, чтобы нормальный индекс строить

                судя по http://stackoverflow.com/a/7538103, mssql тупо не даёт штатного документированного механизма получить это значение пользователю, а что даёт - затем не использует преимущество прямого обращения по заданному адресу (а ведь это самый быстрый способ достать строку из бд)
                Ответить
      • http://ideone.com/sApio9
        Ответить
        • А в идеоне, пишем SQL - подразумеваем MySQL или PostgreSQL?
          Ответить
          • там вообще, прости господи, sqlite
            Ответить
            • а что плохого в sqlite ?
              Ответить
              • То, что это не СУБД.
                Ответить
                • разрабы утверждают обратное SQL database engine. И я их понимаю почему Access СУБД а sqlite нет?
                  Ответить
                  • А что, в Access тоже нет нормальных блокировок и проблема с доступом из нескольких процессов?
                    Ответить
                    • Истинно так
                      Ответить
                      • А за что же Access назвали СУБД?
                        Ответить
                        • формочки делать можно только вроде из за этого. Ну и данные хоть коряво, но можно хранить.
                          Ответить
                          • > формочки делать
                            Оракл, M$$QL, постгрес и мускуль - не СУБД. Ок.
                            Ответить
                            • M$$QL умеет вроде как чего то там делать.
                              Ответить
                    • > нет нормальных блокировок
                      > проблема с доступом из нескольких процессов
                      > тормозные коммиты
                      Это, имхо, судьба любой СУБД на основе расшаренного файла.
                      Ответить
                  • Формально, и то и то субд, но по факту все говно. Я бы честно говоря не стал бы для хранения сотни записей использовать ни то, ни то. Когда речь зайдет о конкурентном доступе, все какашки всплывут наружу, и придется переделывать на другую базу.
                    Но у access, кстати говоря есть возможность настроить синхронизацию через odbc с реальной таблицей, и человек, который более или менее вменяемый, сможет напрямую редактировать эти записи через gui, и даже вставлять их напрямую из excel, что удобно.
                    Ответить
              • Динамическая слабая неявная питуизация.

                http://ideone.com/Jly6kW
                Ответить
              • P.S. Хотя как небольшое embedded хранилище он рулит. Всё лучше, чем фаербёрды и m$$ql express, которые тащут с собой всякие бухгалтерские проги ради табличек со сраной сотней записей...
                Ответить
                • P.P.S. Вспомнилась история с фаербёрдом: юзеры нарекли свой комп COM1 и бедная огнептица не смогла законнектиться к локалхосту.
                  Ответить
                  • А я не смог скомпилировать cfront, потому что авторы одну из директорий исходников назвали aux.
                    Ответить
                    • И после этого M$ еще жалуется, что версию их операционки проверяют как version.indexOf("9") != -1...
                      Ответить
      • > на 2003-ем
        Access-е штолле?
        Ответить
    • Въебал "плюс".
      Ответить

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