#mysql
#mysql
Вопрос:
У меня есть таблица базы данных, подобная этой:
group | detailsID | price
EK | 1 | 1.40
EK | 2 | 1.50
EK | 3 | 1.60
H | 1 | 2.40
H | 2 | 2.50
Теперь я хочу скопировать данные из группы «EK» в группу «H», поэтому цены для идентификаторов detailsID должны быть скорректированы для идентификаторов DETAILSID 1 и 2, а запись для идентификатора detailsID 3 должна быть вставлена для группы «H».
Как я могу сделать это с помощью одного или двух запросов MySQL?
Спасибо!
Комментарии:
1. Возможно ли, что могут быть
H
значения без соответствующегоEK
значения? например,H
группа сdetailsID = 4
, но нетEK
группы сdetailsID = 4
?2. @Nick Нет, это невозможно
3. Это одноразовое действие, которое вы хотите выполнить?
4. Если это так, то ответ @TimBiegeleisen должен делать то, что вы хотите.
5. @Nick :-0 :-0 Также может быть возможно с использованием SP
Ответ №1:
Мы можем попробовать выполнить INSERT INTO ... SELECT
с ON DUPLICATE KEY UPDATE
:
INSERT INTO yourTable (`group`, detailsID, price)
SELECT 'H', detailsID, price
FROM yourTable t
WHERE `group` = 'EK'
ON DUPLICATE KEY UPDATE price = t.price;
Но это предполагает, что существует уникальный ключ на (group, detailsID)
. Если бы это было невозможно, то этот подход не работал бы.
В качестве альтернативы я мог бы сделать это в два этапа. Сначала удалите записи H
группы, затем вставьте обновленные H
записи, которые вы ожидаете.
DELETE
FROM yourTable
WHERE `group` = 'H';
INSERT INTO yourTable (`group`, detailsID, price)
SELECT 'H', detailsID, price
FROM yourTable
WHERE `group` = 'EK';
Я использую описанный выше подход, потому что одно обновление не может удовлетворить ваши требования, поскольку также необходимо вставить новые записи.
Обратите внимание, что вам следует избегать присвоения имен вашим столбцам и таблицам с использованием зарезервированных ключевых слов MySQL, таких как GROUP
.
Комментарии:
1. Спасибо за вашу помощь. Я думаю, что первый подход не сработает в моем случае, потому что у меня также есть столбец ID с первичным ключом. Я забыл упомянуть об этом. Я воспользуюсь вашим вторым подходом. Спасибо.
Ответ №2:
Вы также можете попробовать это, следуя коду, реализованному с использованием хранимых процедур. Очень просто, не так сложно понять. Возможно, вам потребуется изменить тип данных и оптимизировать код в соответствии с требованиями.
DELIMITER $$;
DROP PROCEDURE IF EXISTS update_H $$;
CREATE PROCEDURE update_H()
BEGIN
DECLARE finished INTEGER DEFAULT 0;
DECLARE `group_col` varchar(255) DEFAULT "";
DECLARE `detaildid_col` varchar(255) DEFAULT "";
DECLARE `price_col` varchar(255) DEFAULT "";
DECLARE H_FOUND INTEGER DEFAULT 0;
DECLARE pull_data CURSOR FOR select `group`, `detaildid`, `price` from test.newtab WHERE `group` = 'EK';
DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = 1;
OPEN pull_data;
traverse_data: LOOP
FETCH pull_data INTO group_col, detaildid_col, price_col;
IF finished = 1 THEN
LEAVE traverse_data;
END IF;
SET H_FOUND = (SELECT count(*) from test.newtab where `group` = 'H' AND `detaildid` = detaildid_col);
IF ( H_FOUND = 1 ) THEN
UPDATE test.newtab SET `price` = price_col where `group` = 'H' AND `detaildid` = detaildid_col;
ELSE
INSERT INTO test.newtab (`group`, `detaildid`, `price`) VALUES ('H', detaildid_col, price_col);
END IF;
END LOOP traverse_data;
CLOSE pull_data;
END $$;
DELIMITER ;
Вы можете вызвать эту процедуру, выполнив, call update_H();