【问题标题】:How can I create a self-incrementing ID per day in MySQL?如何在 MySQL 中创建每天自增的 ID?
【发布时间】:2021-07-08 00:58:03
【问题描述】:

我有一张桌子

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 字段是必须的吗?或者我可以在选择中这样做吗? 我想我可以通过一个程序来做到这一点,但是怎么做呢?

感谢您的帮助。 ????

【问题讨论】:

  • 为什么不散列日期?
  • 您问的问题是“idDay 字段是否必要?” - 你是可以回答这个问题的人(我认为这是需要回答的第一个问题)。您认为拥有该领域会取得什么成就?您希望/期望将该字段用于什么(仅使用“id”和“createdAt”字段无法实现)?
  • @Craig ,你是对的,我的意思是如果我只能通过选择来做到这一点,这对我来说不是必需的。
  • 在这种情况下,@sticky bit 的答案将通过在 SELECT 语句中生成每个日期的自动增量来帮助您实现目标

标签: mysql sql auto-increment


【解决方案1】:

您可以使用自 MySQL 8 以来可用的 row_number() 窗口函数。

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

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

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

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

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 &lt; date_add(date(b1.createdat), INTERVAL 1 DAY))更改为b2.createdat &lt;= b1.createdat。)
这也适用于较低的 MySQL 版本,您可以在不更改数字的情况下添加 WHERE 子句(到外部查询)。

【讨论】:

  • 只有当你想要获取的每条记录,你还想要当天所有以前的记录时,它才有效。否则,您将需要一个子查询,此时您不妨使用自联接
  • @ysth:公平点。我编辑了答案来解决这个问题。
【解决方案2】:

您可以只计算选择中的数字(需要 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

【讨论】:

    猜你喜欢
    • 2015-09-11
    • 2019-12-29
    • 2023-03-08
    • 2023-03-15
    • 2013-07-27
    • 2018-12-13
    • 2011-02-18
    • 1970-01-01
    • 2010-11-05
    相关资源
    最近更新 更多