2015-09-14 1 views
1

У меня есть таблица большого заказа. Таблица заказов с несколькими сотнями тысяч записей заказов и недавно добавить новый столбец invoice_no, и мне нужно создать значение invoice_no на основе отдельных (user_id, seller, addtime) для старой записи заказа.колонка обновления 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_NO от INT к BIGINT

-1

Вы можете установить значение столбца счета для идентификатора пользователя, используя эту инструкцию:

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 

Вот это Demo

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, чтобы получить invoice_no из nextval, но не работает. –

+0

Я не понял? Если у вас есть таблица, как вы указали, где номер счета имеет значение null в начале, то выполнение вышеуказанного запроса приведет к их сбросу в таблице, то есть обновит таблицу, а затем просто сделав select, вы получите результат, как ожидалось. Дайте мне знать, если я что-то упустил. –