通过多个组排名进行更新

时间:2019-02-20 20:46:02

标签: mysql sql

基本问题

因此,我正在创建一项服务,客户可以注册并接收神秘玩具。客户给我们分批订单(每个订单都有自己的价格限制),然后我们尝试将每个单独的订单与我们认为也是在该价格限制下的最佳玩具配对。 / p>

客户可以更新他们的偏好,以缩小我们发送给他们的潜在玩具的范围;并非每个客户都会对我们拥有的每个玩具感兴趣。当然,他们不希望我们将相同的玩具发送两次。

问题

如果我有两个表:PotentialToys(列出可以送给哪些客户的玩具,以及它们的价格和按估计值的排名)和ToyOrders(包含客户,每个订单的价格限制以及我们计划给它们的玩具(默认为null,要在UPDATE上设置),如何更新表ToyOrders中的订单以选择既在该订单的价格限制之下又每个客户只能选择一次的玩具?

示例MySQL架构

CREATE TABLE PotentialToys (
    customer   NVARCHAR(25) NOT NULL,
    toy        NVARCHAR(25) NOT NULL,
    price      DECIMAL(5,2) NOT NULL,
    rank       INTEGER NOT NULL
 );

 CREATE TABLE ToyOrders (
   order_id     INTEGER PRIMARY KEY AUTO_INCREMENT,
   customer     NVARCHAR(25) NOT NULL,
   price_limit  DECIMAL(5,2) NOT NULL,
   rank         INTEGER NOT NULL,
   selected_toy NVARCHAR(25)
 );

 INSERT INTO PotentialToys (customer, toy, price, rank) VALUES 
 ('Alice', 'Chemistry Kit', 20.00, 1),
 ('Alice', 'Stuffed Bear', 5.00, 2),
 ('Alice', 'Playing Cards', 10.00, 3),
 ('Bob', 'Playstation', 500.00, 1),
 ('Bob', 'Baseball Monkey', 25.00, 2),
 ('Bob', 'Stuffed Bear', 5.00, 3),
 ('Bob', 'Chemistry Kit', 20.00, 4),
 ('Carlos', 'Magic Trick Set', 50.00, 1),
 ('Carlos', 'Playing Cards', 10.00, 2),
 ('Carlos', 'Banana-Phone', 20.00, 3);

 INSERT INTO ToyOrders (customer, price_limit, rank) VALUES 
 ('Alice', 20.00, 1),
 ('Alice', 15.00, 2),
 ('Alice', 10.00, 3),
 ('Bob', 25.00, 1),
 ('Bob', 25.00, 2),
 ('Bob', 15.00, 3),
 ('Carlos', 25.00, 1);

更新ToyOrder后所需的输出

SELECT order_id, customer, price_limit, selected_toy FROM ToyOrders;

+-------------------------------------------------------------
  | order_id | customer | price_limit    | selected_toy    |
+-------------------------------------------------------------
  | 1        | Alice    |  $20.00        | Chemistry Kit   |
  | 2        | Alice    |  $15.00        | Stuffed Bear    |
  | 3        | Alice    |  $10.00        | Playing Cards   |
  | 4        | Bob      |  $25.00        | Baseball Monkey |
  | 5        | Bob      |  $25.00        | Stuffed Bear    |
  | 6        | Bob      |  $15.00        | NULL            | -- No toys left for Bob under $15. It's OK to leave NULL
  | 7        | Carlos   |  $25.00        | Playing Cards   | -- The magic trick set cost more than the order's price limit, so he gets the next best thing


到目前为止,我已经尝试过:


SET @offset_rank = 0;
UPDATE ToyOrders AS O 
INNER JOIN PotentialToys AS PT 
    ON O.customer = PT.customer
    AND O.rank + @offset_rank = PT.rank 
    AND IF(PT.price <= O.price_limit, TRUE, (@offset_rank := @offset_rank + 1) && FALSE)
SET O.selected_toy = PT.toy;


以上内容仅会为Alice产生正确的输出; Bob和Carlos最终收到了错误的包裹,就像这样:

+-------------------------------------------------------------
  | order_id | customer | price_limit    | selected_toy    |
+-------------------------------------------------------------
  | 1        | Alice    |  $20.00        | Chemistry Kit   |
  | 2        | Alice    |  $15.00        | Stuffed Bear    |
  | 3        | Alice    |  $10.00        | Playing Cards   |
  | 4        | Bob      |  $25.00        | NULL            | -- Should be Baseball Monkey, not NULL
  | 5        | Bob      |  $25.00        | Stuffed Bear    |
  | 6        | Bob      |  $15.00        | NULL            | 
  | 7        | Carlos   |  $25.00        | Banana-Phone    | -- Should be Playing Cards


我应该怎么做?

0 个答案:

没有答案