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

    @Akina
    Сетевой и системный админ, SQL-программист.
    CREATE TABLE schedule ( schedule_id INT PRIMARY KEY,
                            start_time TIME,
                            task_id INT );

    В одной записи - одно время и одна задача. Никаких CSV-наборов.
    Если у задач есть отдельная таблица - то соответственно FOREIGN KEY в неё.
    Ответ написан
    1 комментарий
  • Как найти таблицу в нужной схеме MySQL?

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

    Получите соответствующее сообщение об ошибке.

    дошёл до такой функции

    Сотрите срочно. Существование таблицы (вообще или в определённой схеме) проверяется запросом в INFORMATION_SCHEMA.TABLES.

    SELECT TABLE_SCHEMA, TABLE_NAME
    FROM INFORMATION_SCHEMA.TABLES
    -- WHERE TABLE_NAME = 'my_table_name'
    ;


    что если в другой схеме уже есть таблица с таким названием...

    Ну допустим есть, и что?
    Ответ написан
    Комментировать
  • Как создать правильно уточняющий запрос?

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

    SELECT product.id
    FROM product
    INNER JOIN product_property
    INNER JOIN property
    WHERE property.value IN ( {values list} )
    GROUP BY product.id
    HAVING COUNT(DISTINCT property.value) = {distinct values count}


    Условия связывания и дополнительные ограничения допишете самостоятельно.
    Ответ написан
  • Как импортировать большой JSON (18гб) в MySQL?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Мне нужно загнать всё это дело в MySQL. Какие наиболее оптимальные способы для этого есть?

    Оптимальный - положить этот файл туда, куда может дотянуться MySQL. Импортировать, используя LOAD DATA INFILE, во временную таблицу. Несложным запросом распарсить в рабочие таблицы (как я понимаю, хоть весь файл и невалиден как JSON, но каждая отдельная строка файла есть JSON валидный). И прибить временную таблицу.

    На всё про всё три запроса. Если очень хочется, можно их выполнить и через php, конечно. Но я бы затолкал их в хранимую процедуру (особенно если задача импорта обновлённых данных будет регулярная) и вызывал её - тогда вообще один запрос CALL proc_name;.

    А можно и в один запрос уложиться, если использовать LOAD DATA INFILE с препроцессингом. Тогда и валидность JSON на строку неважна =- лишь бы формат данных в строке не плавал от одной строки к другой.

    А гонять 18 гектар с диска в PHP, а потом от PHP к MySQL - ну несерьёзно.

    PS. Загрузка с использованием LOAD DATA INFILE весьма нетребовательна к объёму оперативной памяти. И неважно, какого размера исходный файл.
    Ответ написан
    Комментировать
  • Как собрать данные в одну таблицу из двух?

    @Akina
    Сетевой и системный админ, SQL-программист.
    мне надо чтоб по артикулу, он определил product_id из другой таблицы и заменил related_sku ( артикул в даный момент) на product_id из другой таблицы.

    Нехорошая идея - портить данные. причём так, что ни повторить, ни откатиться. Куда как лучше создать третье поле
    ALTER TABLE related_products ADD COLUMN related_id INT;

    и уже в него добавить соотв. значения
    UPDATE related_products p
    JOIN another_table a ON p.related_sku = a.sku
    SET p.related_id = a.product_id
    WHERE p.related_id IS NULL

    WHERE нужен на случай повторных запусков второго запроса - вдруг не все соответствия будут получены из-за опечаток, различного написания и пр.
    Ответ написан
    Комментировать
  • Как вывести строчку в mysql workbench?

    @Akina
    Сетевой и системный админ, SQL-программист.
    В MySQL в выходной поток может писАть только запрос SELECT. Без вариантов. Формально - также это могут делать встроенные макросы (например, SHOW) - но всё равно все они есть спрятанный в недрах кода SELECT.

    Триггер выполняется в рамках выполнения запроса INSERT/UPDATE/DELETE, т.е. запроса, для которого запись в выходной поток не разрешена. Соответственно из триггера никакую строку никуда вывести нельзя.
    Ответ написан
    2 комментария
  • Ошибка 1055 в MySQL означает что выбираемые значения должны быть и в GROUP BY и в SELECT одновременно?

    @Akina
    Сетевой и системный админ, SQL-программист.
    Любое поле/выражение выходного набора должно быть либо аргументом агрегатной функции, либо составной частью выражения группировки.

    В данном случае Вы выбираете p.name, которого нет в ->groupBy('p.user') и которое не есть аргумент агрегатки. Добавьте его в выражение группировки, ->groupBy('p.user, p.name') (а если оно уникально в пределах одного p.user, то хватит и ->groupBy('p.name')).
    Ответ написан
    Комментировать
  • Как вывести список клиентов с непрерывной историей за год?

    @Akina
    Сетевой и системный админ, SQL-программист.
    SELECT ID_client
    FROM Transactions_info
    WHERE date_new BETWEEN @first_day_of_period
                       AND @last_day_of_period
    GROUP BY ID_client
    HAVING COUNT(DISTINCT date_new) = DATEDIFF(@last_day_of_period, @first_day_of_period) + 1
    Ответ написан
    6 комментариев
  • Правильный синтаксис при заполнении графы в таблице в соотношении из другой?

    @Akina
    Сетевой и системный админ, SQL-программист.
    UPDATE posts p
    JOIN communitiesusers cu USING (userid)
    SET p.communityid = cu.communityid 
    WHERE p.communityid IS NULL; -- или, может быть, p.communityid = ''
    Ответ написан
    1 комментарий
  • Sequelize - Как исправить ошибку (errno: 150 "Foreign key constraint is incorrectly formed)?

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

    Либо добавляйте столбцы внешнего ключа позже с различными миграциями (только для добавления столбца).
    Ответ написан
    Комментировать
  • Как сместить значение поля position на +1?

    @Akina
    Сетевой и системный админ, SQL-программист.
    CREATE PROCEDURE move_rows ( IN position_move_from INT,
                                 IN position_move_to INT )
    UPDATE test 
    SET pos = CASE WHEN id = position_move_to
                   THEN position_move_from
                   ELSE pos + SIGN(position_move_to - position_move_from)
                   END
    WHERE id BETWEEN LEAST(position_move_from, position_move_to)
                 AND GREATEST(position_move_from, position_move_to)
    ORDER BY id = position_move_to;


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