3

为简洁起见,假设我们有一个numbers包含 2 列的表:id& number

CREATE TABLE numbers(
   id INT NOT NULL AUTO_INCREMENT,
   NUMBER INT NOT NULL,
   PRIMARY KEY ( id )
);

我希望number列自动递增,但在达到 100 后从 1 重新开始,满足以下要求:

  1. 如果还没有记录,则设置number为 1。
  2. 如果表中已有记录:
    1. 如果最后一条记录number小于 100,则设置number为 + 1。
    2. 如果最后一条记录number为 100 或更多,则设置number为 1。

这是我到目前为止所拥有的:

INSERT INTO `numbers` (`number`)
VALUES (
    IF(
        IFNULL(
            (SELECT `number`
            FROM `numbers` as n
            ORDER BY `id` DESC
            LIMIT 1),
            0
        ) > 99,
        1,
        IFNULL(
            (SELECT `number`
            FROM `numbers` as n
            ORDER BY `id` DESC
            LIMIT 1),
            0
        ) + 1
    )
)

这可行,但使用两个相同SELECT的查询。

有什么办法可以去掉重复的SELECT吗?


PS我想在查询中完成所有这些。没有触发器或存储过程。

4

3 回答 3

3

尝试使用模%运算符

INSERT INTO `numbers` (`number`)
VALUES (
          IFNULL(
            (SELECT `number`
            FROM `numbers` as n
            ORDER BY `id` DESC
            LIMIT 1),
            0
        ) % 100 + 1
    )
于 2014-01-10T06:18:59.717 回答
2

您可以使用临时变量。

INSERT INTO `numbers`(`number`) VALUES (
  IF((@a := IFNULL((SELECT number FROM `numbers` AS n ORDER BY id DESC LIMIT 1), 0)) > 99, 1, @a + 1)
);
于 2014-01-10T06:12:54.740 回答
1

我懂了。模数答案很好。我觉得它很“脆弱”,因为它无法处理所述的“100 或更多”要求。将要求改为“如果最后一条记录的编号正好是 100,则将编号设置为 1”即可。

对我来说,这更直观:

INSERT INTO numbers (number)
SELECT 
  CASE 
    WHEN number >= 100 THEN 0
    ELSE COALESCE (number, 0)
  END + 1
FROM numbers
ORDER BY id DESC
LIMIT 1
于 2014-01-10T06:02:49.440 回答