MySQL условная вставка с вставкой .. выберите

0

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

CREATE TABLE customer_price_list (
  customer_price_id int(11) NOT NULL AUTO_INCREMENT,
  customer_account_id int(11) NOT NULL,
  product_id int(11) DEFAULT NULL,
  currency_id int(11) DEFAULT NULL,
  customer_price decimal(7,2) DEFAULT NULL,
  source enum('TRADE_DEFAULT','TEMPLATE','SAGE','MANUAL') DEFAULT NULL,
  PRIMARY KEY (customer_price_id),
  KEY customer_account_id (customer_account_id),
  KEY product_id (product_id),
  KEY currency_id (currency_id),
  KEY source (source)
) 

Принимая только product_id, customer_price и source, образцы данных для одного клиента могут выглядеть (с использованием строки для product_id для иллюстрации):

Prod_1, 10.00, TRADE_DEFAULT 
Prod_2, 20.00, TRADE_DEFAULT 
Prod_3, 25.00, MANUAL 

И другой клиент:

Prod_1, 7.50, SAGE 
Prod_2, 20.00, TRADE_DEFAULT 
Prod_3, 30.00, TRADE_DEFAULT 

Базовая цена за что-то без скидки - это когда TRADE_DEFAULT - это выше показывает, что эти два клиента имели цену TRADE_DEFAULT для двух предметов, но получили скидку на один предмет.

Цены TRADE_DEFAULT устанавливаются путем импорта CSV файла с файлами product_id, currency_id и customer_price. В PHP я просматриваю все строки в CSV и привязываю значения к этому запросу:

insert into customer_price_list  
(customer_price_id, customer_account_id, product_id, currency_id, customer_price, source) 
select 0, customer_account_id, :product_id, :currency_id, :price, 'TRADE_DEFAULT' from customer_account

Это отлично работает, когда client_price_list пуст (для всех комбинаций product_id/currency_id в CSV). Но если некоторые клиенты уже имеют записи product_id/currency_id, это приведет к появлению дополнительных строк (т.е. Для продукта для этого клиента будет две или более цен)

Итак, при обработке CSV я хочу:

A) обновить любое существующее TRADE_DEFAULT до нового значения из CSV (снова запустить из цикла содержимого CSV)

update  customer_price_list set customer_price = :price
        where currency_id=:currency_id and product_id=:product_id and source ='TRADE_DEFAULT'

B) введите цену TRADE_DEFAULT, если у этого клиента нет цены за этот товар/валюту

insert (ONLY IF NO PRICE OF ANY SOURCE IS THERE) into customer_price_list  
(customer_price_id, customer_account_id, product_id, currency_id, customer_price, source) 
select 0, customer_account_id, :product_id, :currency_id, :price, 'TRADE_DEFAULT' from customer_account

Здесь мне нужна помощь. Я искал условные запросы вставки, но я могу найти только, где они вставляют один повторный вызов следующим образом:

insert into table1 (user,rating,last_modified)
select 'user1', 1999, NOW() from table1
where not exists (
select * from table1
where last_modified > '2007-04-13 08:52:41'
and user='user1'
) limit 1

Но я хочу сделать вставку. Выберите и сделайте вставку, если необходимо, для всех клиентов.

Благодарю.

  • 1
    Вы должны иметь возможность использовать расширение ON DUPLICATE KEY UPDATE для оператора вставки.
  • 0
    Спасибо, я отправил ответ на основании вашего предложения.
Теги:

2 ответа

0

Используя предложение @Stavr00, я придумал следующее:

Сначала добавьте индекс по трем столбцам, чтобы сделать продукт/валюту уникальной для каждого клиента:

alter table customer_price_list add  UNIQUE INDEX unq_cust_prod (customer_account_id ASC, product_id ASC, currency_id ASC)

Затем измените запрос:

insert into customer_price_list  
(customer_price_id, customer_account_id, product_id, currency_id, customer_price, source) 
select 0, customer_account_id, :product_id, :currency_id, :price, 'TRADE_DEFAULT' from customer_account
ON DUPLICATE KEY UPDATE customer_price=customer_price;

Сделав обновление, устанавливающее цену на текущее значение, запрос становится только условной вставкой. В сочетании с запросом обновления на шаге A в моем вопросе он делает то, что я хочу.

Наверное, я мог бы использовать UPDATE ON DUPLICATE KEY UPDATE, чтобы выполнить работу другого запроса и сделать все это на одном. Но я бы хотел только обновить существующие записи источника = TRADE_DEFAULT, поэтому не знаю, как это сделать.

Кроме того, похоже, я мог использовать вставку ignore, но поскольку это не означало бы некоторые реальные ошибки, такие как несоответствие типов, я думал, что мое решение было безопаснее.

Комментарии приветствуются!

0

Попробуйте использовать слияние:

https://docs.microsoft.com/en-us/sql/t-sql/statements/merge-transact-sql

Это может быть полезно в вашем случае, так как позволяет вставлять значения на основе условия и обновления, если они уже существуют.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню