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

    @Akina
    Сетевой и системный админ, SQL-программист.
    Используем [NOT] EXISTS
    SELECT *
    FROM user_friend uf1
    WHERE [NOT] EXISTS ( SELECT NULL
                         FROM user_friend uf2
                         WHERE uf2.friend_user_id = uf1.user_id )

    При WHERE EXISTS выбираются пары друзей (записи, имеющие обратную пару), при WHERE NOT EXISTS - записи, не имеющие обратной пары.

    Если для записей, имеющих обратную, нужна только одна пара из двух - добавляем во WHERE внешнего запроса ещё одно условие AND friend_user_id > user_id.
    Ответ написан
    Комментировать
  • Как производить переиндексацию в таблице SQLite?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Вопрос - следствие абсолютного непонимания сути первичного индекса.

    Первичный индекс определяется в таблице для того, чтобы однозначно идентифицировать запись в течение всего времени жизни таблицы.

    Обрати особое внимание - в течение времени жизни именно таблицы. Не записи! То есть то, что запись удалена, ни на что не влияет - отсутствующее значение первичного индекса идентифицирует факт, что запись существовала, но была удалена.

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

    @Akina
    Сетевой и системный админ, SQL-программист.
    Значение по умолчанию (если это не автогенерируемое значение, например, автоинкремент или штамп текущего времени) - это страховка, которая при правильном программировании не должна использоваться вообще.

    Присваивайте нужное значение явно.
    Ответ написан
    3 комментария
  • Возможно ли составить такой SQL запрос?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Ничто не мешает использовать оконный вариант агрегатных функций. Кроме слишком старой версии СУБД, не поддерживающей оконные функции, конечно.
    SELECT MIN(`min_price`) OVER () as `min_price`, 
           MAX(`max_price`) OVER () as `max_price`, 
           `item_id` as `id`
    FROM `product_table` 
    WHERE `id` IN (SELECT  тут запрос)

    Получишь все нужные id, и в каждой строке - нужные MIN и MAX.

    ======================


    Akina, да, версия 5.7.21 и она, я так понимаю, не поддерживает оконные функции.


    SELECT t2.min_price, 
           t2.max_price, 
           t1.item_id as id
    FROM product_table t1
    CROSS JOIN ( SELECT MIN(min_price) AS min_price, 
                 MAX(max_price) AS max_price
                 FROM product_table ) t2
    WHERE t1.id IN (SELECT  тут запрос)
    Ответ написан
  • Возможно ли создать отчёт Excel с помощью SQL?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Excel вполне и сам может получить данные с сервера, причём не только из таблиц, но и результат выполнения запросов любой сложности. Так что SQL тут в общем и не нужен - задача вполне решается средствами VBA. Открыл в Excel файл отчёта, жмакнул кнопку обновления данных, подождал - и наслаждайся готовым результатом.
    Ответ написан
    4 комментария
  • Как получить список чатов по дате отправки сообщений?

    @Akina
    Сетевой и системный админ, SQL-программист.
    SELECT CASE WHEN sender_id = 1
                THEN receiver_id
                ELSE sender_id 
                END AS buddy
    FROM message
    WHERE 1 IN (sender_id, receiver_id)
    GROUP BY buddy
    ORDER BY MAX(sent_at)


    Ну и соответственно
    SELECT user.username
    FROM user
    JOIN ( SELECT CASE WHEN sender_id = 1
                       THEN receiver_id
                       ELSE sender_id 
                       END AS id,
                  MAX(sent_at) sent_at
           FROM message
           WHERE 1 IN (sender_id, receiver_id)
           GROUP BY 1 ) ids USING (id)
    ORDER BY ids.sent_at
    Ответ написан
    3 комментария
  • Как задать связи разного вида с помощью Foreign key?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Любой внешний ключ (FOREIGN KEY в структуре таблицы) задаёт связь типа 1:N (если локальное выражение внешнего ключа не может быть NULL) либо (0-1):N.

    Задание связи 1:1 (и соответственно (0-1):1) требует дополнительного ограничения уникальности на локальной стороне.

    Задание связи M:N требует дополнительной связующей таблицы.

    В данном случае "задание связи" == "создание правила контроля целостности и непротиворечивости данных, контролируемое на стороне сервера соответствующей подсистемой".
    Ответ написан
    Комментировать
  • Postgre Sql DISTINCT массив с ORDER BY?

    @Akina
    Сетевой и системный админ, SQL-программист.
    DISTINCT - это фактически частная форма GROUP BY. А потому к ней относятся все ограничения для GROUP BY в части использования полей источника данных в оконных функциях, выражениях пост-отбора и сортировки.

    Посему используйте поле выходного набора для сортировки.
    SELECT DISTINCT (regexp_split_to_array(commend, E'\\s+'))[:3] AS first_3_words
    FROM orders 
    ORDER BY first_3_words[2];
    Ответ написан
  • Как написать SQL запрос для среза непустых значений?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Общее решение:
    SELECT DISTINCT
           key,
           FIRST_VALUE(value1) OVER (PARTITION BY key 
                                     ORDER BY CASE WHEN value1 IS NULL 
                                                   THEN 1 
                                                   ELSE 0 END, id DESC) AS value1,
           FIRST_VALUE(value2) OVER (PARTITION BY key 
                                     ORDER BY CASE WHEN value2 IS NULL 
                                                   THEN 1 
                                                   ELSE 0 END, id DESC) AS value2,
           FIRST_VALUE(value3) OVER (PARTITION BY key 
                                     ORDER BY CASE WHEN value3 IS NULL 
                                                   THEN 1 
                                                   ELSE 0 END, id DESC) AS value3
    FROM tablename
    -- WHERE key IN ( {список значений} )


    Однако я полностью согласен с тем, что сказал Роман Юрьевич Ипатьев,
    переписать таблицу в нормальную форму
    Ответ написан
    Комментировать
  • Когда нужно писать имя таблицы в запросе?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Каждый сам творец своего геморроя.

    Настоятельная рекомендация. Если источником записей запроса (всего, целиком) является только одна таблица - имена полей можно не указывать. Во всех остальных случаях - указывайте алиас таблицы для абсолютно каждого поля (включая имена обобщённых полей в USING и при NATURAL JOIN), кроме имён полей выходного набора, используемых в пост-группировочных выражениях. Это позволит гарантировать отсутствие неоднозначностей.

    Под понятием "таблица" следует понимать строго один экземпляр исходного набора данных. Иными словами, запрос, в котором используется две копии одной таблицы, либо используется дополнительная синтетическая таблица констант, запросом с источником данных из одной таблицы не является.

    ---

    В некоторых диалектах указание алиаса может быть обязательно и по причине интерференции имён из разных пространств.

    Например, в хранимых объектах MySQL при совпадении имени поля таблицы с именем локальной переменной обращение без указания алиаса - это всегда обращение к переменной. Поэтому для MySQL правило ещё строже - алиас указывай всегда.

    И даже такая строгость порой недостаточна. Пример. Обратите внимание на сортировку - в ней id интерпретируется как имя переменной, а не имя поля выходного набора, и потому результат "странный". Кстати, это тот случай, когда вообще ничто не поможет, кроме использования выражения выходного поля вместо его имени.
    Ответ написан
    Комментировать
  • Как создать скрипт для получения данных из sql БД?

    @Akina
    Сетевой и системный админ, SQL-программист.
    MySQL умеет выгружать результат выполнения запроса в файл.
    У MySQL есть встроенный планировщик.

    Так что создаём Event Procedure, которая выгружает результат нужного запроса в файл в нужном формате, запускаем Event Scheduler... и всё.
    Ответ написан
    Комментировать
  • Как связать много сущностей к одной в результате?

    @Akina
    Сетевой и системный админ, SQL-программист.
    SELECT for_output
    FROM ( SELECT name AS film_name, name AS for_output
           FROM films
         UNION ALL
           SELECT films.name, comments.comment
           FROM films 
           JOIN comments USING (film_id) ) total
    ORDER BY film_name, film_name <> for_output
    Ответ написан
    Комментировать
  • Как сделать вложенность в json через SQL запрос?

    @Akina
    Сетевой и системный админ, SQL-программист.
    DEMO

    В общем, вложенные подзапросы либо цепь CTE, каждый со своим уровнем агрегирования.
    Ответ написан
    1 комментарий
  • Как правильно составить sql запрос с условием?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Схематично:
    SELECT orders.column,
           COALESCE(books.column, deposits.column) AS column
    FROM orders 
    LEFT JOIN books ON orders.type = 'book' AND orders.id = books.order_id
    LEFT JOIN deposits ON orders.type = 'deposit' AND orders.id = deposits.order_id
    Ответ написан
    1 комментарий
  • Показать все значения где другое значение count > 1?

    @Akina
    Сетевой и системный админ, SQL-программист.
    call_id, где есть больше одного значение value

    SELECT call_id
    FROM tablename
    GROUP BY call_id
    HAVING COUNT(DISTINCT value) > 1
    Ответ написан
    Комментировать
  • Как в одном SQL запросе вывести идентификаторы клиентов, у которых нет счёта?

    @Akina
    Сетевой и системный админ, SQL-программист.
    SELECT client
    FROM ( SELECT DISTINCT client
           FROM Dep
         UNION ALL
           SELECT client_id
           FROM Contact ) total
    GROUP BY 1
    HAVING COUNT(*) = 1
    Ответ написан
    Комментировать
  • Может кто подскажет правильно ли составил запрос sql?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Запрос неверен синтаксически.
    1. Каждый JOIN обязан иметь свой ON. Это только MySQL/MariaDB лояльно относится к таким вещам.
    2. Литералы даты должны быть обрамлены кавычками - это как минимум. А кроме того, формат литерала даты должен чётко соответствовать таковому для используемой СУБД - возможно, даже нужно использовать функцию преобразования строкового значения в дату.
    3. Формально - запрос должен быть завершён символом точки с запятой.

    Запрос неверен логически.
    1. Отсутствует связь между заказом/менеджером и покупателем.
    2. Отсутствует подсчёт общей суммы заказов покупателя.
    3. Не предусмотрен вариант, когда у покупателя посередь периода сменился менеджер (менеджеры увольняются, да...). Впрочем, он не предусмотрен и в задании...
    4. Задание требует "с 01.01.2013", т.е. включительно, а в условии отбора используется строгое неравенство.

    Всё остальное - правильно.
    Ответ написан
    Комментировать
  • Как правильно составить запрос для поиска по JSON полю в mySql?

    @Akina
    Сетевой и системный админ, SQL-программист.
    запрос для выборки всех записей у которых в поле 'condition' есть "action": "6"

    SELECT DISTINCT action.*
    FROM action
    CROSS JOIN JSON_TABLE(action.`condition`,
                          '$[*].action' COLUMNS (action INT PATH '$')) jsontable
    WHERE jsontable.action = 6


    https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=c3e97c...
    Ответ написан
    Комментировать
  • В чем различие 2х запросов?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Основное различие в том, что первый использует картезианское произведение с отбором, что давно уже считается bad practice.

    В остальном именно эти два запроса абсолютно эквивалентны с точностью до порядка выполнения. Операция "запятая" имеет приоритет ниже, чем операция JOIN, т.е. в первом запросе выполняется неявное STRAIGHT_JOIN. И если СУБД не умеет наплевать на это, первый запрос может порождать неоптимальный план выполнения даже при актуальной статистике данных.

    В более сложных запросах использование запятой, особенно в комбинации с JOIN, вообще способно полностью поломать запрос, вплоть до синтаксической некорректности. А потому настоятельно рекомендуется вместо запятой использовать CROSS JOIN.
    Ответ написан
    Комментировать
  • Как правильно спроектировать связь БД между двумя товарами?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Вопрос: как мне правильно спроектировать таблицу для связей между этими товарами. Чтобы каждый из этих товаров ссылался друг на друга?

    CREATE TABLE groups_of_goods (
        group_id BIGINT UNSIGNED NOT NULL,
        product_id BIGINT UNSIGNED NOT NULL,
        PRIMARY KEY (group_id, product_id),
        FOREIGN KEY fk_product (product_id) REFERENCES product (product_id)
    );


    Соответственно если твои труселя входят в одну группу и ссылаются друг на друга, то в таблице будут 2 записи - (123, 10) и (123, 15).

    Кстати, такая схема обеспечивает и принцип "вассал моего вассала ...". Т.е. "пиджак малиновый" может ссылаться на "брюки малиновые" (через группу 456) и "пиджак в полоску" (через группу 789), но при этом последние два друг на друга ссылаться не будут, ибо разные группы.
    Ответ написан
    2 комментария