За последние 24 часа нас посетили 17760 программистов и 1621 робот. Сейчас ищут 1815 программистов ...

Выборка, суммирование и удаление в одном запросе

Тема в разделе "MySQL", создана пользователем Krepostnoi, 25 ноя 2016.

  1. Krepostnoi

    Krepostnoi Новичок

    С нами с:
    25 ноя 2016
    Сообщения:
    4
    Симпатии:
    0
    Приветствую.

    Помогите составить правильный запрос в БД.

    Задача такая: Есть две идентичные таблицы (название колонок, количество столбцов и т.д. Всё совпадает).

    Мне нужно взять данные из первой таблицы, делая выборку на основании суммы двух колонок, при условии, что эта сумма больше заданного мною числа (это число известно до выполнения запроса) и перенос этих данных во вторую таблицу. При этом, из первой таблицы данные надо удалить.

    Всё, что я смог сделать - это работающий запрос на выборку и перенос данных:

    INSERT INTO Table1 (Col1, Col2, Сol3) SELECT Col1, Col2, Сol3 FROM Table2 HAVING SUM(Col4+Col5)>'100';

    но он работает не так, как мне нужно. Он переносит только по одной строке, а мне надо перенести все строки, которые попадают под условие "SUM(Col4+Col5)>'100'"

    Как к этому "Чуду" прикрутить удаление, я вообще не понял. Единственное, что смог собрать, это:

    DELETE FROM Table1 WHERE (SELECT * FROM Table2 having SUM(Col4+Col5)>'100');

    Но такой запрос не работает.

    Структура таблицы (вторая таблица идентична):

    `Table1` (
    `bid` int(11) unsigned NOT NULL AUTO_INCREMENT,
    `Col1` varchar(35) NOT NULL,
    `Col2` varchar(32) NOT NULL,
    `Col3` varchar(32) NOT NULL,
    `Col4` int(11) DEFAULT NULL,
    `Col5` int(11) DEFAULT NULL,
    PRIMARY KEY (`bid`)
    )
     
  2. alexforce2

    alexforce2 Активный пользователь

    С нами с:
    25 дек 2013
    Сообщения:
    71
    Симпатии:
    12
    Насколько я знаю, одним запросом здесь не обойтись, поэтому чтобы не нарушить целостность данных, т.е. чтобы не было такого случая что данные удалились из одной таблицы, но не успели вставиться в вторую таблицу(свет отключили, синтаксическая ошибка) - все запросы обвернуть в транзакцию.

    Этот запрос
    Код (Text):
    1. DELETE FROM Table1 WHERE (SELECT * FROM Table2 having SUM(Col4+Col5)>'100');
    надо писать так
    Код (Text):
    1. DELETE FROM `Table1` WHERE `bid` IN (
    2.     SELECT `bid` FROM `Table2` having SUM(Col4+Col5)>'100'
    3. );
    --- Добавлено ---
    В целом должно получиться так
    Код (Text):
    1. START TRANSACTION;
    2.    INSERT INTO `Table1` (`Col1`, `Col2`, `Сol3`)
    3.       SELECT `Col1`, `Col2`, `Сol3` FROM `Table2` HAVING SUM(Col4+Col5)>'100';
    4.  
    5.    DELETE FROM `Table1` WHERE `bid` IN (
    6.      SELECT `bid` FROM `Table2` having SUM(Col4+Col5)>'100'
    7.    );
    8. COMMIT;
     
  3. Krepostnoi

    Krepostnoi Новичок

    С нами с:
    25 ноя 2016
    Сообщения:
    4
    Симпатии:
    0
    Изначально, я допистил небольшую неточность в описании:

    По логике тут должно быть так:

    INSERT INTO `Table2` (`Col1`, `Col2`, `Сol3`) SELECT `Col1`, `Col2`, `Сol3` FROM `Table1` HAVING SUM(Col4+Col5)>'100';

    Т.е. выборка осуществляется для второй таблицы (в которой данных нет), на условиях первой таблицы (в которой данные есть).

    Но такой запрос, переносит только одну запись (которая была первая в bid). Иногда переносит две записи, но закономерности я не понял.

    А в этом запросе явный логический косяк

    DELETE FROM `Table1` WHERE `bid` IN (SELECT `bid` FROM `Table2` having SUM(Col4+Col5)>'100'

    Тут две таблицы, хотя данные надо удалять только из одной таблицы (из первой). И разумеется, никакие данные он не удаляет.
     
  4. alexforce2

    alexforce2 Активный пользователь

    С нами с:
    25 дек 2013
    Сообщения:
    71
    Симпатии:
    12
    @Krepostnoi, я не знаю в какой таблице есть данные, а в какой нету - это тебе придётся разобраться из какой в какую вставлять, в какой удалять.
    Данный запрос вставляет только одну строку, потому что запрос выборки находит только одну строчку, чтобы проверить сколько строк будет вставлено во вторую таблицу, выполни запрос
    Код (Text):
    1. SELECT `Col1`, `Col2`, `Сol3` FROM `Table1` HAVING SUM(Col4+Col5)>'100';
    и посмотри сколько строк он выдаст.
     
  5. Krepostnoi

    Krepostnoi Новичок

    С нами с:
    25 ноя 2016
    Сообщения:
    4
    Симпатии:
    0
    Спасибо.

    Я так понимаю, что сделать эти действия одним запросом не получится. Т.е. одновременно выборку, перенос и удаление всех нужных записей.
     
  6. alexforce2

    alexforce2 Активный пользователь

    С нами с:
    25 дек 2013
    Сообщения:
    71
    Симпатии:
    12
    Нет, одним не получиться.
    А чем не устраивает вариант с двумя запросами, обвёрнутыми в транзакцию?
     
  7. Krepostnoi

    Krepostnoi Новичок

    С нами с:
    25 ноя 2016
    Сообщения:
    4
    Симпатии:
    0
    Мне таких запросов придется выполнить целую пачку, чтобы перенести записи по одной. Но сейчас уже понял, что их и так и так придется выполнять несколькими запросами.

    Собственно спасибо. Вопрос исчерпан. :)