Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > MySQL > Update с сортировкой по связям со второй таблицей


Автор: maxipub 2.7.2018, 15:42
Здравствуйте!

Есть две таблицы: список складов и список товарных позиций:

Код

CREATE TABLE IF NOT EXISTS `mod_stock_list` (
  `stock_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `user_id` int(10) unsigned NOT NULL,
  `stock_name` varchar(32) NOT NULL,
  `stock_city_id` int(10) unsigned NOT NULL,
  UNIQUE KEY `stock_id` (`stock_id`)
) ENGINE=MyISAM  DEFAULT CHARSET=cp1251 AUTO_INCREMENT=8;


CREATE TABLE IF NOT EXISTS `mod_store_items` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `user_id` int(10) unsigned NOT NULL,
  `real_goods_id` int(10) unsigned NOT NULL,
  `spec_id` int(10) unsigned NOT NULL,
  `cost` int(10) unsigned NOT NULL,
  `cart_id` int(10) unsigned NOT NULL DEFAULT '0',
  `stock_id` int(10) unsigned NOT NULL,
  UNIQUE KEY `id` (`id`),
  KEY `user_id` (`user_id`),
  KEY `real_goods_id` (`real_goods_id`),
  KEY `cart_id` (`cart_id`)
) ENGINE=MyISAM  DEFAULT CHARSET=cp1251 AUTO_INCREMENT=188104;


Нужно произвести бронирование товарных позиций за заказом (грубо говоря, делалось примерно так: UPDATE mod_store_items AS i SET i.cart_id=$cart_id WHERE i.cart_id=0 LIMIT $order_count). Но появилась необходимость учитывать склад позиций (stock_id), и логика тут такая:

1. В первую очередь бронируем (SET i.cart_id=$cart_id) все, что есть по текущему складу (i.stock_id=$stock_id);
2. Далее (если таких позиций меньше, чем нам нужно - $order_count) бронируем все, что есть в текущем городе (mod_stock_list AS L ... L.stock_city_id=$stock_city_id);
3. И если мы все еще не выбрали $order_count записей для обновления - бронируем любые другие (без приоритетов).

Первое что пришло в голову - просто добавить LEFT JOIN mod_stock_list AS L ON L.stock_id=i.stock_id OR L.stock_city_id=$stock_city_id, но очевидно что далее нужно будет использовать сортировку для следования логике бронирования (пункты 1 - 2 - 3). Ведь условия ON/WHERE это просто ограничители, приоритеты они ни как не расставляют. Но MySQL не хочет принимать запрос на UPDATE, в котором больше одной таблицы (даже если обновляется только одна из них), и есть одновременно и ORDER и LIMIT. Так что этот красивый вариант отпал сам собой.

Есть другие идеи?

Мне пока в голову пришел только велосипед - сделать это через 3 отдельных запроса, и на PHP проверять результаты их выполнения (количество затронутых строк), и выполнять один за другим (с корректировкой LIMIT) до тех пор, пока общее количество обновленных записей не достигнет $order_count. Но это какой-то жуткий велосипед. smile 

Автор: Akina 2.7.2018, 16:59
Ну собсно обычная сумма с накоплением... я бы использовал пользовательскую переменную при требуемой сортировке, которая для всех складов в указанной сортировке даст резервируемое на этом складе количество. А дальше, если надо, во внешнем запросе отфильтровать нулевые.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)