2015-09-14 98 views
1

我有一個大的訂購表。具有幾十萬個訂單記錄的訂單表最近添加了一個新的列invoice_no,我需要根據舊訂單記錄的不同(user_id,seller,addtime)創建invoice_no值。基於不同列的Mysql更新列

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?

回答

1

我覺得作爲變種你可以試試這個

UPDATE `TEST_ORDER` SET `INVOICE_NO` = CRC32(CONCAT(`USER_ID`, `SELLER`, `ADDTIME`)) 

但.. CRC32將要給你很多受騙者的.. 這肯定會有幫助:

UPDATE `TEST_ORDER` SET `INVOICE_NO` = CONV(SUBSTRING(CAST(SHA(CONCAT(`USER_ID`, `SELLER`, `ADDTIME`)) AS CHAR), 1, 16), 16, 10) 

它將對沒有受騙者數百萬條記錄。

也改變INVOICE_NOINTBIGINT

-1

您可以使用此語句發票列的值設置爲用戶ID:

update TEST_ORDER SET INVOICE_NO=USER_ID 
where INVOICE_NO IS NULL; 
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) 
+0

非常感謝你,是工作。但是,發票號碼是從函數調用中選擇的。 SELECT nextval('invoice_no')AS invoice_no。我應該如何用這個函數調用來替換@ rn + 1? –

+0

我替換sql以從nextval獲取invoice_no,但不起作用。 –

+0

我沒有得到?如果您有一張表,並且開頭的invoice num爲空,那麼運行上面的查詢將會在表中重置它們,這意味着它會更新表格,然後只做select就會按預期給出結果。讓我知道如果我失去了一些東西。 –