Mysql更新列基于distinct列

时间:2015-09-14 04:13:18

标签: mysql insert-update

我有一张大订单表。订单表包含几十万个订单记录,最近添加了一个新列invoice_no,我需要根据旧订单记录的distinct(user_id,seller,addtime)创建invoice_no值。

CREATE TABLE `TEST_ORDER`(  
  `ORDER_ID` INT(11),
  `USER_ID` INT(11),
  `SELLER` VARCHAR(50),
  `ADDTIME` INT(11),
  `GOODS_NAME` VARCHAR(50),
  `PRICE` FLOAT(11,2),
  `INVOICE_NO` INT(11)
);

INSERT into `TEST_ORDER` (`ORDER_ID`, `USER_ID`, `SELLER`, `ADDTIME`, 
`GOODS_NAME`, `PRICE`, `INVOICE_NO`)
values('1','1','AMAZON','1399109546','BOOK 1','10',NULL);

INSERT into `TEST_ORDER` (`ORDER_ID`, `USER_ID`, `SELLER`, `ADDTIME`, 
`GOODS_NAME`, `PRICE`, `INVOICE_NO`) 
values('2','1','AMAZON','1399109546','BOOK 2','20','NULL');

INSERT into `TEST_ORDER` (`ORDER_ID`, `USER_ID`, `SELLER`, `ADDTIME`, 
`GOODS_NAME`, `PRICE`, `INVOICE_NO`) 
values('3','2','EBAY','1438582766','BOOK 3','10',NULL);


INSERT into `TEST_ORDER` (`ORDER_ID`, `USER_ID`, `SELLER`, `ADDTIME`, 
`GOODS_NAME`, `PRICE`, `INVOICE_NO`) 
values('4','2','EBAY','1438582766','BOOK 4','20',NULL);


INSERT into `TEST_ORDER` (`ORDER_ID`, `USER_ID`, `SELLER`, `ADDTIME`, 
`GOODS_NAME`, `PRICE`, `INVOICE_NO`) 
values('5','3','AMAZON','1399109546','BOOK 1','10',NULL);

预期结果

enter image description here

这可以通过正常的更新sql查询来完成,或者我需要编写一个存储过程并循环每个订单记录以检查订单是否属于同一invoice_no?

2 个答案:

答案 0 :(得分:2)

是的,这可以通过一个更新命令来完成,但是您需要应用一些技巧来使用不同的数据获取发票的运行数量,然后使用自联接进行更新。查询看起来像

update TEST_ORDER t1
join (
  select 
  ORDER_ID,
  @rn:= if ( (@prev_uid = USER_ID && @prev_seller = SELLER && @prev_addtime = ADDTIME),@rn,@rn+1) as rn,
  @prev_uid:= USER_ID,
  @prev_seller:= SELLER,
  @prev_addtime:= ADDTIME
  from TEST_ORDER , (select @rn:=0,@prev_uid:=0,@prev_seller=null,@prev_addtime:=null)x
  order by USER_ID,SELLER,ADDTIME
)t2
on t1.ORDER_ID = t2.ORDER_ID
set t1.INVOICE_NO = t2.rn

这是演示

mysql> select * from TEST_ORDER ;
+----------+---------+--------+------------+------------+-------+------------+
| ORDER_ID | USER_ID | SELLER | ADDTIME    | GOODS_NAME | PRICE | INVOICE_NO |
+----------+---------+--------+------------+------------+-------+------------+
|        1 |       1 | AMAZON | 1399109546 | BOOK 1     | 10.00 |       NULL |
|        2 |       1 | AMAZON | 1399109546 | BOOK 2     | 20.00 |       NULL |
|        3 |       2 | EBAY   | 1438582766 | BOOK 3     | 10.00 |       NULL |
|        4 |       2 | EBAY   | 1438582766 | BOOK 4     | 20.00 |       NULL |
|        5 |       3 | AMAZON | 1399109546 | BOOK 1     | 10.00 |       NULL |
+----------+---------+--------+------------+------------+-------+------------+

mysql> update TEST_ORDER t1
    -> join (
    ->   select 
    ->   ORDER_ID,
    ->   @rn:= if ( (@prev_uid = USER_ID && @prev_seller = SELLER && @prev_addtime = ADDTIME),@rn,@rn+1) as rn,
    ->   @prev_uid:= USER_ID,
    ->   @prev_seller:= SELLER,
    ->   @prev_addtime:= ADDTIME
    ->   from TEST_ORDER , (select @rn:=0,@prev_uid:=0,@prev_seller=null,@prev_addtime:=null)x
    ->   order by USER_ID,SELLER,ADDTIME
    -> )t2
    -> on t1.ORDER_ID = t2.ORDER_ID
    -> set t1.INVOICE_NO = t2.rn;
Query OK, 5 rows affected (0.04 sec)
Rows matched: 5  Changed: 5  Warnings: 0

mysql> select * from TEST_ORDER ;
+----------+---------+--------+------------+------------+-------+------------+
| ORDER_ID | USER_ID | SELLER | ADDTIME    | GOODS_NAME | PRICE | INVOICE_NO |
+----------+---------+--------+------------+------------+-------+------------+
|        1 |       1 | AMAZON | 1399109546 | BOOK 1     | 10.00 |          1 |
|        2 |       1 | AMAZON | 1399109546 | BOOK 2     | 20.00 |          1 |
|        3 |       2 | EBAY   | 1438582766 | BOOK 3     | 10.00 |          2 |
|        4 |       2 | EBAY   | 1438582766 | BOOK 4     | 20.00 |          2 |
|        5 |       3 | AMAZON | 1399109546 | BOOK 1     | 10.00 |          3 |
+----------+---------+--------+------------+------------+-------+------------+
5 rows in set (0.00 sec)

答案 1 :(得分:-1)

您可以使用以下语句将发票列值设置为用户ID:

update TEST_ORDER SET INVOICE_NO=USER_ID
where INVOICE_NO IS NULL;