Задать вопрос
  • Почему 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 комментарий
  • Как создать текстовые файлы из списка в .txt?

    @Akina
    Сетевой и системный админ, SQL-программист.
    for /f %x in (file.txt) do echo.>%x.txt
    Кодировка текстового файла должна соответствовать кодировке имён в файловой системе.
    Ответ написан
  • Какой необходимо составить запрос mysql для генератора случайного поста по рейтингу?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Ну типа так.
    WITH cte AS (
        SELECT *, SUM(rating) OVER (ORDER BY id) cum_rating
        FROM table
    )
    SELECT
    FROM cte t1
    JOIN (SELECT RAND() * MAX(cum_rating) rnd_rating
          FROM cte) t2 ON t2.rnd_rating BETWEEN t1.cum_rating - t1.rating AND t1.cum_rating

    Реально, конечно, не BETWEEN, а два неравенства, по верхней границе - строгое.
    Ответ написан
  • Помощь с запросом MySQL?

    @Akina
    Сетевой и системный админ, SQL-программист.
    SELECT car_model.* 
    FROM car_model 
    JOIN car_mark ON car_model USING (id_car_mark)
    WHERE car_mark.name='AC'
    Ответ написан
    Комментировать
  • Какие запросы для SQL считаются сложными запросами?

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

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

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

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

    @Akina
    Сетевой и системный админ, SQL-программист.
    Список требуемых id должен быть источником данных запроса, причём базовым. И при возможном отсутствии связанных записей связывание должно быть внешнее.
    SELECT service.id AS service_id, COUNT(subs.id) AS c
    FROM ( SELECT 13 id UNION 
           SELECT 74    UNION
           SELECT 71    UNION
           SELECT 72 ) AS service
    LEFT JOIN Subscriptions subs ON subs.service_id = service.id AND subs.msisdn=992777757031
    GROUP BY service.id
    ORDER BY c DESC;
    Ответ написан
  • Как определить изменения для товаров в заказе?

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

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

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

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

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

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

    @Akina
    Сетевой и системный админ, SQL-программист.
    WITH 
    cte1 AS ( SELECT id, name, ROW_NUMBER() OVER (ORDER BY name) rn
              FROM t1 ),
    cte2 AS ( SELECT id, name, ROW_NUMBER() OVER (ORDER BY name) rn
              FROM t2 )
    SELECT cte1.id id1, cte1.name name1, cte2.id id2, cte2.name name2
    FROM cte1
    JOIN cte2 USING (rn, id);


    https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=b5a064...

    Хотя, конечно, бред рафинированный. С точки зрения логики.
    Ответ написан
  • Как определить ближайшую к текущей дату на Oracle SQL?

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

    @Akina
    Сетевой и системный админ, SQL-программист.
    Порядок кляуз в запросе чётко определён в документации, и никаких изменений и перестановок не предполагает (исключение - кляуза INTO при помещении результата в переменную, для которой описано 3 разных местоположения).
    SELECT u.*, t.type_name, t.description 
    FROM users AS u 
    LEFT JOIN type_user AS tu ON tu.id_user = u.id 
    LEFT JOIN types AS t ON tu.id_type = t.id
    WHERE u.id = 1;
    Ответ написан
    Комментировать
  • Как решить 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.
    Ответ написан
    Комментировать
  • Как использовать CONVERT_TZ и AS?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Алиас выходного поля нельзя использовать во WHERE.

    Правильно - использовать копию вычисляющего значения выражения:
    SELECT event, 
           CONVERT_TZ(time, '+00:00', '-04:00') AS time1 
    FROM events 
    WHERE CONVERT_TZ(time, '+00:00', '-04:00') between '2021-06-24 00:00:00' AND '2021-06-24 23:59:59' 
      AND lang = 'ru'

    Расширение MySQL также допускает использовать алиас выходного поля в HAVING (при условии что в выражении не используются оконные функции):
    SELECT event, 
           CONVERT_TZ(time, '+00:00', '-04:00') AS time1 
    FROM events 
    WHERE lang = 'ru'
    HAVING time1 between '2021-06-24 00:00:00' AND '2021-06-24 23:59:59'
    Ответ написан
    Комментировать
  • Как выводить записи не раннее получаса и не позднее часа в sql?

    @Akina
    Сетевой и системный админ, SQL-программист.
    WHERE created_at BETWEEN CURRENT_TIMESTAMP - INTERVAL 1 HOUR
                         AND CURRENT_TIMESTAMP - INTERVAL 30 MINUTE
    Ответ написан
    Комментировать
  • Как вычесть у одного пользователя число и добавить его другому?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Лучше делать всё в одном запросе:
    UPDATE users u1
    CROSS JOIN users u2
    SET u1.amount = u1.amount - $summa,
        u2.amount = u2.amount + $summa
    WHERE u1.id = $client
      AND u2.id = $shop;


    Во-первых, один запрос - проще. Пусть даже сам запрос и сложнее.

    Во-вторых, если, например, в структуре таблицы имеется ограничение CHECK (amount >= 0), а сумма такова, что у клиента баланс уйдёт в минус - в таком случае ни одна из записей не будет изменена.
    Ответ написан
    Комментировать
  • Что не так с моим запросом?

    @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
    Ответ написан
  • Может ли роскомнадзор заблокировать домен третьего уровня appspot.com?

    @Akina
    Сетевой и системный админ, SQL-программист.
    РКН не блокирует домены - блокируются IP-адреса (диапазоны, подсети).

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

    @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

    Само собой если некоего значения нет ни в одном из полей, его не будет и в результате.
    Ответ написан
    Комментировать