Ответы пользователя по тегу SQL
  • Как вывести те поля, где один или два слова?

    pi314
    @pi314
    Президент Солнечной системы и окрестностей
    Если нужен велосипед, то "одно или два слова" означает, "количество пробелов (без учета ведущих и замыкающих) < 2"
    А вообще, в Оракле для таких вещей с незапамятных времен есть REGEXP_LIKE.
    Ответ написан
    Комментировать
  • Правильно ли я создал sql запрос?

    pi314
    @pi314
    Президент Солнечной системы и окрестностей
    Нет, запрос сделан неправильно! Он, дополнительно к тому, что требуется, выберет еще и пользователей, которые написали комментарий, даже если их собственные статьи никто не комментировал... не говоря уже о том, что если нет явной необходимости аггрегирования полей в группе, то использование GROUP BY там, где можно обойтись DISTINCT - дорогое удовольствие (почему - объясню дальше, а пока, просто для сравнения, его план и "стоимость"):
    5ab3f036b072d356066942.png
    Чтобы просто получить нужный результат, его, конечно, можно тупо дополнить еще одним JOIN с article_comment_association, но это все еще очень плохо: во-первых, JOIN с таблицей комментариев там просто лишний, во-вторых, GROUP BY - все то же разбазаривание ресурсов:
    5ab3f0802b299318193006.png
    Вот, для сравнения, стоимость DISTINCT vs. GROUP BY:
    5ab3f08c07b85920446589.png
    (Все эти неправильные варианты приводить не буду, чтоб их случайно не скопипейстили в систему управления ядерным реактором!)

    В этом смысле вариант, предложеный Rsa97 , уже лучше, т.к. дает правильный результат.
    SELECT name FROM users
      WHERE id IN (
        SELECT user_id FROM article
          WHERE id IN (
            SELECT article_id FROM article_comment_association
          )
      );

    Однако, использование subquery в таком порядке, действительно, не позволяет использовать distinct:
    5ab3f109468d6235394789.png
    Фишка в том, что subquery, как правило, создают временную таблицу, обычно, в памяти, но если ее мало, то и на диске. Так что, если есть возможность заменить их на JOIN (а она есть почти всегда!), это нужно делать, не стесняясь.

    А вот феншуйная (она же - правильная, легко читаемая, очевидная и эффективная) версия запроса:
    SELECT distinct users.name from users
      INNER JOIN article ON (article.user_id = users.id)
      INNER JOIN article_comment_association ON (article.id = article_comment_association.article_id)

    ... и ее план:
    5ab3f135365b0576447042.png
    Мораль истории: в реляционной базе данных самый прямой путь к нужному результату, как правило, оказывается наиболее эффективным. Как общее правило - начинать нужно с самого большого множества записей, исключая за раз как можно больше ненужного, и давая оптимизатору использовать индексы.
    Ответ написан
    3 комментария
  • Привязана ли команда SUM (mysql) к оператору SELECT FROM?

    pi314
    @pi314
    Президент Солнечной системы и окрестностей
    Хорошо, что проблема разрешилась, но - просто для ясности... Оператор, точнее, аггрегирующая функция SUM() связанa с указанным полем того множества, из которого производится SELECT, и суммирует значения этого поля для записей, прошедших все фильтры (WHERE и HAVING). В простейшем случае это одна таблица (тогда подразумевается GROUP BY по первичному ключу, т.е., эффективно, вообще никакого), но может быть и JOIN, и подзапрос и.д. и тогда уже, конечно, нужно явно указывать GROUP BY, который будет относиться к одному или нескольким полям ЭТОГО ЖЕ множества. Проще говоря, аггрегирующие функции относятся к множеству, полученному в результате группировки и применяются к тем записям, которые были "свернуты" этой группировкой.
    Ответ написан
    Комментировать
  • Почему GROUP BY работает?

    pi314
    @pi314
    Президент Солнечной системы и окрестностей
    Есть разница между "работает" и "выдаёт детерминированный результат". В данном примере ни разу не очевидно, какой именно результат можно ожидать в полях, которые не агрегированы и по которым не происходит группировки. Кто-то решит втулить туда значение из первой записи, попавшей в группировку, кто-то - из последней, кто-то вообще решит включать в результат только группы с идентичным значением этого поля... короче, вариантов море, и все неочевидны, и не определены стандартом. В нормально спроектированных системах в таких случаях принято выбирать наиболее очевидный вариант, т.е. выдавать ошибку. Можно, конечно, поступать иначе, но полагаться на такую систему - было бы как минимум стремно.
    Ответ написан
    Комментировать
  • Когда набор связанных данных можно считать базой данных?

    pi314
    @pi314
    Президент Солнечной системы и окрестностей
    Вопрос философского толка, однако ;) Первое условие уже содержится в самом вопросе - данные в наборе должны быть связаны. Ну, а второе напрямую вытекает из первого и заключается в том, как же именно они связаны. Базой данных можно считать набор данных, связанных в контексте некоторой предметной области, причем связаных так, что это позволяет делать выборки данных, отвечающие на вопросы этой предметной области.

    Например, в контексте поиска телефонных номеров...
    Городской телефонный справочник - это база данных, т.к. данные в нем связаны таким образом, что позволяют находить номера. Если же мы перекроим его так, что каждому телефонному номеру будет поставлен в соответствие номер страницы, на которой этот номер напечатан, а каждой фамили - сумма отдельных цифр в телефонном номере, этот набор данных перестанет быть базой данных в контексте заявленной области (хотя в нем будут все данные из исходного набора, и даже больше)... зато легко может стать таковой для каких-нибудь гороскопно-нумерологических задач.
    Ответ написан
    3 комментария
  • Как составить сложный SQL запрос на создание таблиц со связями и объединением запросов?

    pi314
    @pi314
    Президент Солнечной системы и окрестностей
    offtop: откуда в деревне Простоквашино взялась городская библиотека?

    А по сути - два соображения:

    1. Скрипты создания таблиц некорректно называть SQL, т.к. SQL - язык запросов к данным, а его расширение для манипуляции структурой БД, на котором пишутся эти скрипты, называется DDL (Data Definition Language).

    2. И, наконец, с непривычки решать такие задачи лучше графически... А потом уже писать скрипты.
    Ответ написан
  • Для чего пишут LIMIT в UPDATE?

    pi314
    @pi314
    Президент Солнечной системы и окрестностей
    LIMIT имеет смысл только в сочетании с ORDER BY. Например, выдать конфетку трем победителям:
    UPDATE users SET candy=candy+1 ORDER BY score DESC LIMIT 3
    Ответ написан
    Комментировать