Задать вопрос
Ответы пользователя по тегу SQL
  • Как правильно составить 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 комментария
  • Как получить все проекты, у которых нет связи с определенным юзером через 2 таблицу?

    @Akina
    Сетевой и системный админ, SQL-программист.
    я хочу получить все проекты, у которых нет связи с id 4

    SELECT p.*
    FROM project p
    WHERE NOT EXISTS ( SELECT NULL
                       FROM project_user u
                       WHERE p.project_id = u.project_id
                         AND u.user_id = 4 )
    Ответ написан
    Комментировать
  • Как сделать умножение в Select?

    @Akina
    Сетевой и системный админ, SQL-программист.
    SELECT CASE valuta WHEN 1 THEN price
                       WHEN 0 THEN price * 73
                       ELSE NULL 
                       END AS price_in_rub, 
           ...
    FROM ...
    WHERE ...
    Ответ написан
    1 комментарий
  • Зачем нужны alias-ы в БД?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Основное назначение алиасов - устранение неоднозначности при наличии одноимённых таблиц/полей.

    Дополнительно - удобство именования, особенно когда оригинальные имена длинные.

    Если ещё смыслы, но они минорны.
    Ответ написан
    Комментировать
  • Как отсортировать разные группы по разным методам?

    @Akina
    Сетевой и системный админ, SQL-программист.
    ORDER BY CASE WHEN parent_id IN (0,51,52)
                  THEN 1
                  ELSE 2 
                  END ASC,
             CASE WHEN parent_id IN (0,51,52)
                  THEN name
                  ELSE ''
                  END ASC,
             CASE WHEN parent_id IN (0,51,52)
                  THEN ''
                  ELSE name
                  END DESC
    Ответ написан
    Комментировать
  • Почему Select выдает меньше колонок чем в нем прописано?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Причина простая. Лапша вместо кода. Это и не позволяет понять, что есть что.

    Отформатируем:

    with AAA(A) as (
        select 1 union 
        select 2 union 
        select 3 union 
        select 4 union 
        select 5
    )
    select 'А01' as "id",
           1 as "sensor",
           generate_series('2021-07-01 00:00:00', '2021-07-31 23:59:59', '10 sec'::interval) as "time",
           t.status[floor(random()* 4 + 1)::int] 
    from (select array_agg(distinct AAA.A) as "status" from AAA ) as t ,
         round((random()* 400 - 200)::numeric, 2) as "value"

    Теперь сразу видно, что value не является полем выходного набора. Это алиас синтетической таблицы в секции FROM.

    PS. За логику и даже просто за синтаксическую корректность я так и вовсе молчу...
    Ответ написан
    1 комментарий
  • Какие запросы для SQL считаются сложными запросами?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Подобный текст в вакансиях обычно означает вовсе даже не сложные запросы. Обычно речь о сильнозамороченных запросах, которые полны текста и со стороны смотрятся лихозакрученным многоэтажным безобразием, но на самом деле простые и плоские как блин. Тупая выборка, тупой подзапрос, тупые вычисления... всё, что надо - это аккуратность и способность донести понимание, что есть что и зачем делается, не расплескав, до конца запроса. Ибо если потерял мысль на полпути - проще стереть и начать заново, чем вспоминать, что это и нахрена ты это тут сделал.

    Сложные, реально сложные, запросы бывают (по крайней мере навскидку) двух типов.

    Первый - это запросы, которые имеющимися (как правило в конкретной СУБД либо в конкретной версии) средствами должны выполнить то, что в данной версии не имплементировано. Типичнейший пример из этой категории - например, динамические сводные запросы в большинстве СУБД. Или эмуляция рекурсивных запросов и оконных функций там, где их нет.

    Второй - это запросы, в которых для оптимизации скорости выполнения приходится далеко отходить от прямого, "в лоб", выполнения, и строить достаточно замороченные тексты, которые реализуют ту же логику, но из-за особенностей выполнения запроса сервером гораздо более эффективны. Тут, пожалуй, типичный запрос привести трудно, но достаточно характерным примером может служить выбор между WHERE [NOT] EXISTS и LEFT JOIN WHERE IS [NOT] NULL (и обязательным гноблением WHERE [NOT] IN).
    Ответ написан
    2 комментария
  • Как определить изменения для товаров в заказе?

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

    Да как обычно при хранении timeline. Первым делом настраиваем права и запрещаем обновление и удаление. Записи можно только добавлять. Вторым - вводим автоматически присваиваемое поле штампа времени создания версии заказа. И, собственно, всё.

    Для получения состояния заказа на любой момент времени (актуальное состояние или в прошлом) используем один несложный запрос. То же - если нужно получить разницу между текущим и предыдущим состояниями. Оконные функции делают это на счёт "раз".

    И никакие логи не нужны.
    Ответ написан
    5 комментариев
  • Выведение всех максимальных значений?

    @Akina
    Сетевой и системный админ, SQL-программист.
    SELECT * 
    FROM table t1
    WHERE NOT EXISTS ( SELECT NULL
                       FROM table t2
                       WHERE t1.salary < t2.salary )

    Ну или в переводе на русский - вывести всех сотрудников, для которых нет сотрудника с бОльшей зряплатой.
    Ответ написан
    Комментировать
  • Как определить ближайшую к текущей дату на Oracle SQL?

    @Akina
    Сетевой и системный админ, SQL-программист.
    SELECT *
    FROM tablename
    WHERE datecolumn <= CURRENT_DATE
    ORDER BY datecolumn DESC 
    FETCH FIRST 1 ROWS WITH TIES
    Ответ написан
    6 комментариев
  • Как решить SQL задачку про пропускную систему?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Если пронумеровать записи для одного работника в течение одного дня, то нечётные - это входы, чётные соответственно выходы.

    CTE, ROW_NUMBER().
    Ответ написан
  • Можно ли и как составить запрос в БД, чтобы получить статистические данные?

    @Akina
    Сетевой и системный админ, SQL-программист.
    WITH RECURSIVE
    cte1 AS ( SELECT MIN(DATE(create_date)) mindate, MAX(DATE(create_date)) maxdate
              FROM shops
              UNION ALL
              SELECT MIN(DATE(create_date)) mindate, MAX(DATE(create_date)) maxdate
              FROM users ),
    cte2 AS ( SELECT MIN(mindate) mindate, MAX(maxdate) maxdate
              FROM cte1 ),
    dates AS ( SELECT mindate thedate, maxdate
               FROM cte2
               UNION ALL
               SELECT thedate + INTERVAL 1 DAY, maxdate
               FROM dates
               WHERE thedate < maxdate ),
    shopstat AS ( SELECT DATE(create_date) thedate, COUNT(*) cnt
                  FROM shops
                  GROUP BY thedate ),
    userstat AS ( SELECT DATE(create_date) thedate, COUNT(*) cnt
                  FROM users
                  GROUP BY thedate )
    SELECT thedate `date`, 
           COALESCE(shopstat.cnt, 0) shops, 
           COALESCE(userstat.cnt, 0) users
    FROM dates
    LEFT JOIN shopstat USING (thedate)
    LEFT JOIN userstat USING (thedate)


    Если нужны данные за определённый период - убрать cte1 и cte2, использовать границы диапазона в dates (поле maxdate - не нужно, убрать), добавить соотв. WHERE в остальные CTE.
    Ответ написан
    Комментировать
  • Что не так с моим запросом?

    @Akina
    Сетевой и системный админ, SQL-программист.
    SELECT main.id,
           ( SELECT COUNT(*) 
             FROM news 
             WHERE main.id = news.main_id ) news,
           ( SELECT COUNT(*) 
             FROM articles
             WHERE main.id = articles.main_id ) articles
    FROM main
    ORDER BY news DESC;


    Предполагается, что main(id) есть уникальное поле (скорее всего первичный ключ).
    Ответ написан
    2 комментария
  • Как удалить дубликаты Oracle SQL?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Вывод дубликатов:
    SELECT t1.*
    FROM table t1
    WHERE EXISTS ( SELECT NULL
                   FROM table t2
                   WHERE t1.id <> t2.id -- выражение первичного ключа
                     AND t1.column = t2.column -- для всех полей, кроме первичного ключа


    Удаление:
    DELETE 
    FROM table t1
    WHERE EXISTS ( SELECT NULL
                   FROM table t2
                   WHERE t1.id > t2.id -- оставить только запись с минимальным ID
                     AND t1.column = t2.column
    Ответ написан