@NetyNicka

Как перелить данные из одной таблицы MySql в другую, при этом обновить в первой?

Здраствуйте товарищи! В очередной раз нужна ваша помощь!
Есть 2 почти одинаковых таблицы:
CREATE TABLE `queue` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) unsigned NOT NULL,
  `product_id` int(11) unsigned NOT NULL,
  `count` tinyint(3) unsigned NOT NULL,
  `time` int(11) unsigned NOT NULL,
  `state` enum('draft','pending','accepted') NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `user_id_product_id` (`user_id`,`product_id`)
) ENGINE=InnoDB AUTO_INCREMENT=20267 DEFAULT CHARSET=utf8;

и
CREATE TABLE `offers` (
  `user_id` int(11) unsigned NOT NULL,
  `product_id` int(11) unsigned NOT NULL,
  `count` tinyint(3) unsigned NOT NULL,
  `finish_time` int(11) unsigned NOT NULL,
  PRIMARY KEY (`user_id`,`product_id`),
  UNIQUE KEY `user_id_product_id` (`user_id`,`product_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


В очереди создаются записи, которые должны будут по скрипту или кнопке переливаться в таблицу offers, если у них state= 'pending' и в случае успеха, в queue меняется статус на accepted.

Сейчас используется следующее решение на yii2:
public static function executeQueue(array $keys = [])
	{
		$returnArray = [];
		if (count($keys) > 0) {
			$rows = Queue::find()->where([
				'state' => Queue::STATE_PENDING,
				'id' => $keys
			])->all();
		} else {
			$rows = Queue::findAll(['state' => Queue::STATE_PENDING]);
		}
		foreach ($rows as $specialOffer) {
			$record = new Offer();
			$record->user_id = $specialOffer->user_id;
			$record->product_id = $specialOffer->product_id;
			$record->count = $specialOffer->count;
			$record->finish_time = $specialOffer->time;
			if ($record->validate() && $record->save()) {
				$specialOffer->state = Queue::STATE_ACCEPTED;
				$specialOffer->save();
				$returnArray[] = $specialOffer->id;
			}
		}
		return $returnArray;
	}

Который в общем-то справляется с сотнями записей, но необходимо обрабатывать тысячи!
Самое простое решение, переписать на Sql.
Перенести данные из одной таблицы в другую получилось просто:
INSERT INTO offers (
	user_id,
	product_id,
	count,
	finish_time
) SELECT
	user_id,
	product_id,
	count,
	time
FROM
	queue
WHERE
	state = 'pending'

Но как поменять state pending->accepted у всех записей, которых коснулся запрос?
Более того, остается вопрос о конфликтах, ведь теоретически в offers уже может существовать запись с заданным user_id, product_id (UNIQUE KEY `user_id_product_id` (`user_id`,`product_id`))
Прошу наставить на путь истинный и подсказать, как реализовать запрос (или даже процедуру)?
  • Вопрос задан
  • 1043 просмотра
Решения вопроса 1
@NetyNicka Автор вопроса
1) Перелить данные:
INSERT DELAYED IGNORE INTO offers (
  user_id,
  product_id,
  count,
  finish_time
) SELECT
  user_id,
  product_id,
  count,
  time
FROM
  queue
WHERE
  state = 'pending'


2) Поменять статусы:
UPDATE queue
SET state = 'accepted'
WHERE
	state != 'accepted'
AND (product_id, user_id) IN (
	SELECT
		product_id,
		user_id
	FROM
		offers
)
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
@nozzy
Symfony, Laravel, SQL
Используйте
select * from table for update;
update table ....;
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы