如何在 MySQL 中每天创建一个自增 ID?

How can I create a self-incrementing ID per day in MySQL?

我有一个table

bills
( id INT NOT NULL AUTOINCREMENT PRIMARY KEY
, createdAt TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
, idDay INT NULL
);

我希望每一天的idDay字段的第一条记录为1,并从那里继续递增,示例:

|    id    |    createdAt   | idDay |
|----------|----------------|-------|
| 1        | 2021-01-10     |   1   |
| 2        | 2021-01-10     |   2   |
| 3        | 2021-01-11     |   1   |
| 4        | 2021-01-11     |   2   |
| 5        | 2021-01-11     |   3   |
| 6        | 2021-01-12     |   1   |
| 7        | 2021-01-13     |   1   |
| 8        | 2021-01-13     |   2   |

idDay 字段是必须的吗?或者我可以在 select 中执行此操作吗? 我想我可以通过程序来做到这一点,但是怎么做呢?

感谢您的帮助。

您可以使用 row_number() window 功能自 MySQL 8.

SELECT id,
       createdat,
       row_number() OVER (PARTITION BY date(createdat)
                          ORDER BY id) idday
       FROM bill;

(或 ORDER BY createdat,如果定义顺序,则不是 id。)

但由于 window 函数是在应用 WHERE 子句后计算的,如果过滤了一天的先前记录,记录的数字可能会有所不同。从你的问题中不清楚这是否是一个问题。如果这是一个问题,您可以在派生的 table 中使用查询或使用它创建一个视图并进行处理。

另一个选项是计算“较旧”记录的相关子查询。

SELECT b1.id,
       b1.createdat,
       (SELECT count(*) + 1
               FROM bill b2
               WHERE b2.createdat >= date(b1.cratedat)
                     AND b2.createdat < date_add(date(b1.createdat), INTERVAL 1 DAY)) 
                     AND b2.id < b1.id) idday
       FROM bill b1;

(如果createdat定义了顺序,将b2.createdat < date_add(date(b1.createdat), INTERVAL 1 DAY))改为b2.createdat <= b1.createdat。)
这也适用于较低的 MySQL 版本,您可以在不更改数字的情况下添加 WHERE 子句(到外部查询)。

您可以只计算 select 中的数字(需要 createdAt 上的索引才能正常工作):

select b.id, b.createdAt, count(b2.id)+1 as idDay
from bill b
left join bill b2 on b2.createdAt=b.createdAt and b2.id < b.id
where ...
group by b.id