我是 SQL 的初学者,我试图在没有任何运气的情况下寻找答案。
我想自动生成具有以下区别的发票编号:
例如:ENG_2022_1、ENG_2022_2 ... ENG_2023_1
例如:FR_2022_1、FR_2022_2、FR_2022_3、……FR_2023_1
我想过设置一个自动递增的字段,但是除非有解决方法,否则这不适用于结构和年份区分?
另一个解决方案是在开具发票之前获取年份和结构,并在编号之前将其与发票编号的 SQL MAX 进行比较,但我不确定该解决方案有多好?
任何帮助将不胜感激
自动递增列的使用似乎很明显,但是,在您的情况下,您希望在每年年初重新开始编号,因此应该提供一些东西。
我会在发票表中为此至少创建四列:
YEAR(invoice_date)
得到年份。FR
或 ENG
.要创建发票编号,您需要知道当年序列中的发票数量。这可以在单独的查询中检索:
SELECT
COUNT(*) AS invoice_count
FROM
invoice_table
WHERE
invoice_sequence = :sequence AND
YEAR(invoice_date) = YEAR(:date);
在此查询中,
:sequence
和 :date
是占位符,用于绑定您要查找的值。
之后您可以插入实际发票。这是此类插入物的模型:
INSERT INTO
invoice_table
(invoice_date,
invoice_sequence,
invoice_number,
......)
VALUES
(:date,
:sequence,
CONCAT(:sequence, '_', YEAR(:date), '_', :invoiceCount),
......)
在此查询中,
:date
、:sequence
和 :invoiceCount
是占位符,用于绑定我们已知的值。请注意,在某些情况下,您不能重复相同的占位符名称。在那种情况下,使用像:name1
和:name2
这样的东西,或者只是?
.
请注意,您可以将查询以检索插入查询中的计数作为子查询。为了更好的可读性,我在这里没有这样做。
我建议您分别存储序列、年份和数字。
为此创建三列:
invoice_number INTEGER,
invoice_year INTEGER,
invoice_sequence VARCHAR(4)
并获得最终价值
SELECT CONCAT(invoice_sequence, '_', invoice_year, '_', invoice_number) inv_full number
FROM MY_INVOICES
之后创建将在插入时自动生成发票编号的触发器:
CREATE TRIGGER GENERATE_INVOICE_NUMBER
BEFORE INSERT
ON MY_INVOICES FOR EACH ROW
BEGIN
SELECT IFNULL(MAX(invoice_number), 0) + 1
INTO new.invoice_number
FROM MY_INVOICES
WHERE invoice_year = new.invoice_year
AND invoice_sequence = new.invoice_sequence;
END
此处函数
MAX
用于获取指定序列和年份的先前数字的最大值,以考虑发票删除的可能性并避免违反数字唯一性。