Ответы пользователя по тегу MySQL
  • Как правильно указать значение SET?

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

    Для того. чтобы вставляемое значение не квотировалось, следует использовать плейсхолдер из 2 знаков вопроса:
    PreparedStatement ps = plugin.SQL.getConnection().prepareStatement("UPDATE PlayerBlocks SET ?? = ? WHERE UUID=?");

    Тогда первый передаваемый параметр - имя поля для обновления. 2 и 3 соответственно значения (новое и для условия отбора).
    Ответ написан
    4 комментария
  • Какой необходимо составить запрос 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'
    Ответ написан
    Комментировать
  • Почему 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;
    Ответ написан
  • Как убрать лишние значения при 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...

    Хотя, конечно, бред рафинированный. С точки зрения логики.
    Ответ написан
  • Как правильно указать 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;
    Ответ написан
    Комментировать
  • Можно ли и как составить запрос в БД, чтобы получить статистические данные?

    @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 комментария
  • Как можно добавить данные в несколько таблиц через один insert into?

    @Akina
    Сетевой и системный админ, SQL-программист.
    MySQL не поддерживает многотабличный INSERT.

    Варианты:
    1. Хранимая процедура
    2. Триггер (но нужно решать проблему с передачей параметров для остальных таблиц)
    Ответ написан
    9 комментариев
  • Как исправить Fatal error in defaults handling. Program aborted?

    @Akina
    Сетевой и системный админ, SQL-программист.
    mysql думает что в файле отсутствует группа, но там все есть

    Чудес не бывает. Если сервер считает, что файл кривой, то он прав. А ты чего-то не замечаешь.

    пробовал ставить кодировку ANSI

    Должен быть чистый ASCII.
    Ответ написан
    Комментировать
  • Почему value="" записывает пустоту, а не NULL?

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

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

    SELECT 500 queue, operator, os.avg_os, ss.avg_ss
    FROM ( SELECT operator,AVG(valuation) avg_os
           FROM oper_survey 
           WHERE queue = '500' AND `date` BETWEEN '2021-06-01' AND '2021-06-16' 
           GROUP BY operator ) os
    JOIN ( SELECT operator, AVG(valuation) avg_ss
           FROM service_survey 
           WHERE queue = '500' AND `date` BETWEEN '2021-06-01' AND '2021-06-16' 
           GROUP BY operator ) ss USING (operator)


    Более сложный вариант - какой-то operator отсутствует в одной из таблиц. Тогда надо собрать список из обеих таблиц, и к нему привязывать считающие подзапросы.

    SELECT 500 queue, operator, COALESCE(os.avg_os, 0) avg_os, COALESCE(ss.avg_ss, 0) avg_ss
    FROM ( SELECT operator FROM oper_survey WHERE queue = '500'
           UNION 
           SELECT operator FROM service_survey WHERE queue = '500' ) op
    LEFT JOIN ( SELECT operator,AVG(valuation) avg_os
                FROM oper_survey 
                WHERE queue = '500' AND `date` BETWEEN '2021-06-01' AND '2021-06-16' 
                GROUP BY operator ) os USING (operator)
    LEFT JOIN ( SELECT operator, AVG(valuation) avg_ss
                FROM service_survey 
                WHERE queue = '500' AND `date` BETWEEN '2021-06-01' AND '2021-06-16' 
                GROUP BY operator ) ss USING (operator)
    Ответ написан
    Комментировать
  • Как выполнить подзапрос в 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 комментария
  • Репликация MySQL 8?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Правильно ли понимаю, что в случае отказа слейва на какое-то условное кол-во времени за которое mysql-bin.log заротейтится при достижении условных 100М, то при восстановлении слейв сервера, данные, которые находятся уже в архивном логе не будут записаны?


    Нет, неправильно.

    max_binlog_size устанавливает размер ОДНОГО файла лога. Когда указанный размер достигнут, создаётся новый, и запись идёт уже в него. А старый никуда не девается, и будет нормально передан на слейв, когда его функционирование восстановится.
    Ответ написан
  • Есть ли способ автоматически добавить все пустые строки в MySQL с AUTO_INCREMENT до какого-то максимального значения?

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

    WITH RECURSIVE 
    cte AS ( SELECT 1 n
             UNION ALL
             SELECT n + 1  FROM cte WHERE n < 1000 )
    INSERT INTO tablename (id)
    SELECT NULL FROM cte t1 CROSS JOIN cte t2;
    Ответ написан
    Комментировать
  • Можно ли совместить два запроса с группировкой?

    @Akina
    Сетевой и системный админ, SQL-программист.
    SELECT priority,
           SUM(time >= '2021-06-04' AND time < '2021-06-05') AS today,
           SUM(time >= '2021-06-03' AND time < '2021-06-04') AS yesterday
    FROM  tableX
    WHERE time >= '2021-06-03' AND time <= '2021-06-05'
    GROUP BY priority
    Ответ написан
    1 комментарий
  • Как удалить дубли строк в MySQL в таблице, связанной с другими?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Погуглил, вроде как все советуют такое решение:

    Дерьмо. Забудь.

    Есть большая БД на 50гб, и стоит задача удалить дубли в одной из таблиц.
    [skipped]
    Но проблема в том что в других таблицах есть связи через внешние ключи с моей основной.


    Порядок действий.

    Запрос 0. Выполнить полное резервное копирование. Убедиться, что полученный бэкап валиден.

    Запрос 1. Для каждого набора дубликатов изменить реферальные значения в связанных таблицах, присвоить значению реферального поля значение, взятое из записи с минимальным (или максимальным) значением первичного индекса. Выполняется отдельно для каждой таблицы, имеющей внешний ключ в целевую.

    Запрос 2. Удалить все записи-дубликаты, кроме имеющих минимальное (или максимальное) значение первичного индекса.

    DEMO fiddle
    Ответ написан
    Комментировать