【问题标题】:MySql increment order ID relative to accountMySql 相对于账户增加订单 ID
【发布时间】:2020-06-26 09:23:31
【问题描述】:

考虑表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 分配一个增量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 所说的,这里有一个提供类似示例的答案:https://stackoverflow.com/a/2404587/9373031

【问题讨论】:

    标签: mysql sql sql-update


    【解决方案1】:

    如果您运行的是 MySQL 8.0,您可以使用 row_number() 执行此操作。但是您需要另一列来使排序保持一致。假设表的主键是order_id,可以这样做:

    select
        order_id,
        account_id,
        row_number() over(partition by account_id order by order_id) account_order_id
    from orders
    

    乍一看,我实际上并不建议存储这些数字,因为您需要维护这些派生信息 - 您可以创建一个视图来代替。但既然你要求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
    

    请注意,这会立即更新整个表(而原始解决方案在存储过程中有一个循环); SQL 是一种基于集合的语言,通常不需要循环。

    【讨论】:

    • 像魅力一样工作!我想知道是否可以在AccountOrderID 上以某种方式为每个AccountID 使用MAX(),并将过滤器仅应用于具有NULL 值的那些,以及它是否可以提高性能(希望它有意义)。谢谢。
    猜你喜欢
    • 2015-02-02
    • 1970-01-01
    • 2014-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-31
    相关资源
    最近更新 更多