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

    @Akina
    Сетевой и системный админ, SQL-программист.
    SELECT value,
           SUM(value = val1) total_1,
           SUM(value = val2) total_2
    FROM ( SELECT val1 value FROM test
           UNION 
           SELECT val2 FROM test ) total
    CROSS JOIN test
    GROUP BY value
    ORDER BY value;

    DEMO

    Само собой если некоего значения нет ни в одном из полей, его не будет и в результате.
    Ответ написан
    Комментировать
  • Почему value="" записывает пустоту, а не NULL?

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

    @Akina
    Сетевой и системный админ, SQL-программист.
    Удалить таблицу main - за полной её ненадобностью и бессмысленностью. Вместо неё создать представление на основе остальных двух таблиц,
    Ответ написан
    Комментировать
  • Как правильно сделать запрос в бд?

    @Akina
    Сетевой и системный админ, SQL-программист.
    SELECT *
    FROM chat
    WHERE NOT EXISTS ( SELECT NULL
                       FROM group_chat 
                       WHERE chat.id = chat_id
                         AND group_id = 9 )

    Кстати, заменив NOT EXISTS на EXISTS, можно получить тот же результат, что и в запросе из текста вопроса. При правильном индексировании он будет, скорее всего, даже более эффективен.
    Ответ написан
  • Как выполнить подзапрос в SQL (SELECT с передачей параметра из основного запроса?

    @Akina
    Сетевой и системный админ, SQL-программист.
    SELECT users.name AS username,
           count(orders.id) AS orders_count 
    FROM users
    JOIN orders ON orders.user_id=users.id
    GROUP BY users.name

    Если нужно вывести и пользователей, у которых нет заказов, с нулевым количеством, то использовать LEFT JOIN.

    PS. Запрос из текста вопроса тоже корректен и должен дать правильный результат. Причём с 50% вероятностью он будет преобразован в мой (точнее, оба дадут один и тот же план выполнения). Остальные 50% - на то, что он будет выполнен итерационно (и тогда скорее всего просто будет выполняться дольше).
    Ответ написан
    2 комментария
  • Ошибка SQL HASMGR?

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

    То есть надо бы изменить порядок создания таблиц. Сначала создать SALEREPS, и только потом OFFICES...

    ---

    Но вообще структура какая-то бредовая. Одна таблица имеет FK на другую, которая имеет FK на первую... как-то логики совсем не прослеживается.

    И просто пересортировкой порядка создания таблиц такое не лечится. Сначала все таблицы, потом все внешние ключи - единственное решение... но сперва надо разобраться с логикой зависимостей таблиц.

    ---

    И это... всегда указывайте точно поле, на которое должен ссылаться внешний ключ. Не надейтесь на умолчания.
    Ответ написан
    Комментировать
  • SQL-запрос: как выбрать тех, у кого авторизация ТОЛЬКО из приложения?

    @Akina
    Сетевой и системный админ, SQL-программист.
    SELECT DISTINCT user_id
    FROM enter t1
    WHERE NOT EXISTS ( SELECT NULL
                       FROM enter t2
                       WHERE enter_source = 'web' 
                         AND t1.user_id = t2.user_id )
      AND EXISTS ( SELECT NULL
                   FROM enter t3
                   WHERE enter_source IN ('ios', 'android')
                     AND t1.user_id = t3.user_id );
    Ответ написан
    Комментировать