MySql приращение идентификатора заказа относительно счета - PullRequest
0 голосов
/ 14 марта 2020

С учетом таблицы orders:

+-----------+----------------+
| AccountID | AccountOrderID |
+-----------+----------------+
|         1 |           NULL |
|         5 |           NULL |
|         1 |           NULL |
|         6 |           NULL |
|         5 |           NULL |
|         2 |           NULL |
|         6 |           NULL |
|         4 |           NULL |
|         4 |           NULL |
|         5 |           NULL |
+-----------+----------------+

Как можно назначить инкрементный идентификатор для AccountOrderID относительно Account ID, чтобы он выглядел следующим образом:

+-----------+----------------+
| AccountID | AccountOrderID |
+-----------+----------------+
|         1 |              1 |
|         5 |              1 |
|         1 |              2 |
|         6 |              1 |
|         5 |              2 |
|         2 |              1 |
|         6 |              2 |
|         4 |              1 |
|         4 |              2 |
|         5 |              3 |
+-----------+----------------+

До сих пор я использовал users со столбцом с именем LastOrderID и триггером для его увеличения вместе с AccountOrderID (который прекрасно работает):

DELIMITER $$
CREATE TRIGGER `new_order` BEFORE INSERT ON maindb.orders
    FOR EACH ROW BEGIN
        UPDATE users
            SET LastOrderID = LastOrderID + 1
        WHERE AccountID = NEW.AccountID;
        SET NEW.AccountOrderID = (SELECT LastOrderID FROM Credentials WHERE AccountID = NEW.AccountID);
    END;
$$
DELIMITER ;

Но я считаю, что Таблица users не должна использоваться для этой цели: есть ли другой способ добиться этого результата?

РЕДАКТИРОВАТЬ

Даже если это именно то, что сказал GMB, Вот ответ, предлагающий похожий пример: { ссылка }

1 Ответ

1 голос
/ 14 марта 2020

Вы можете сделать это с row_number(), если вы используете MySQL 8.0. Но вам нужен еще один столбец, чтобы сделать сортировку последовательной. Предполагая, что первичным ключом таблицы является order_id, вы можете сделать: вместо этого можно создать вид. Но так как вы запросили запрос update:

update orders o
inner join (
    select 
        order_id, 
        row_number() over(partition by account_id order by order_id) account_order_id
    from orders
) o1 on o1.order_id = o.order_id
set o.account_order_id = o1.account_order_id

Обратите внимание, что это обновляет всю таблицу сразу (в то время как исходное решение имеет al oop в хранимой процедуре); в SQL, который является языком на основе множеств, обычно нет необходимости в циклах.

...