解决方案#1 – 使用额外的列
演示
SQL
INSERT INTO bills (id_interess, id_bill_tmp, id_bill) VALUES (
1, -- (Change this value appropriately for each insert)
IF(LEFT((SELECT id_bill FROM
(SELECT MAX(CONCAT(LEFT(id_bill, 8),
LPAD(SUBSTR(id_bill, 10), 10, 0))) AS id_bill
FROM bills) b1), 4) = DATE_FORMAT(CURDATE(),'%Y'),
IFNULL(
(SELECT id_bill_tmp
FROM (SELECT id_bill_tmp
FROM bills
WHERE CONCAT(LEFT(id_bill, 8),
LPAD(SUBSTR(id_bill, 10), 10, 0)) =
(SELECT MAX(CONCAT(LEFT(id_bill, 8),
LPAD(SUBSTR(id_bill, 10), 10, 0)))
FROM bills)) b2),
0),
0)
+ 1,
CONCAT(DATE_FORMAT(CURDATE(),'%Y%m%d'), '-' , id_bill_tmp));
笔记
实际上,查询看起来稍微复杂一点,因为MySQL不允许您直接使用插入的同一个表中的子选择.如here所述,使用在其周围缠绕另一个子选择的方法来规避这一点.
解决方案#2 – 没有额外的列
演示
SQL
INSERT INTO bills (id_interess, id_bill) VALUES (
1, -- (Change this value appropriately for each insert)
CONCAT(DATE_FORMAT(CURDATE(),'%Y%m%d'),
'-' ,
IF(LEFT((SELECT id_bill
FROM (SELECT MAX(CONCAT(LEFT(id_bill, 8),
LPAD(SUBSTR(id_bill, 10), 10, 0))) AS id_bill
FROM bills) b1), 4) = DATE_FORMAT(CURDATE(),'%Y'),
IFNULL(
(SELECT id_bill_tmp
FROM (SELECT SUBSTR(MAX(CONCAT(LEFT(id_bill, 8),
LPAD(SUBSTR(id_bill, 10), 10, 0))), 9)
AS id_bill_tmp
FROM bills) b2),
0),
0)
+ 1));
笔记
这与上面的行相同,但是通过SUBSTR(id_bill,10)从第10个字符位置开始从id_bill的右边部分提取,得到id_bill_tmp中的数值.
一步一步细分
> CONCAT(…)通过将其各部分连接在一起来组装字符串.> DATE_FORMAT(CURDATE(),’%Y%m%d’)将当前日期格式化为yyyymmdd(例如20170923).> IF(…,< x>,< y>)用于检查已存在的最近日期是否是当前年份:如果是,则数字部分应继续增加序列,否则重置为1.> LEFT(< date>,4)从最近的日期获得年份 – 从id_bill的前4个字符中提取.> SELECT MAX(…)AS id_bill FROM bills从id_bill获取最新的日期序列号,并给它一个别名id_bill. (请参阅上面的注释,了解为什么子查询也需要赋予别名(b1),然后包装在另一个SELECT中).请参阅以下两个步骤,了解如何构造字符串,以便MAX可用于排序.> CONCAT(LEFT(id_bill,8),…)正在构造一个字符串,通过将日期部分与用零填充的序列号组合,可用于上述排序.例如. 201709230000000001.> LPAD(SUBSTR(id_bill,10),10,0)用零填充序列号(例如0000000001,以便MAX可用于排序.)(请参阅Paul Spiegel的评论,了解为什么需要这样做 – 例如所以序列号10在9之后而不是在1之后排序.> DATE_FORMAT(CURDATE(),’%Y’)将当前日期格式化为一年(例如2017年),用于上述(3)中提到的IF比较.> IFNULL(< x>,< y>)用于第一行,因为不会找到现有行,因此结果将为NULL.在这种情况下,数字部分应从1开始.> SELECT SUBSTR(MAX(…),9)AS id_bill_tmp FROM bills从id_bill中选择最新的日期序列号(如上所述),然后提取其序列号,该序列号始终从字符位置9开始.同样,这个子查询需要别名(b2)并包装在另一个SELECT中.> 1递增序列号. (注意,总是这样做,因为在上述情况下使用0,其中序列号应设置为1).