mysql 使用SQL和PHP每年对发票和不同结构进行编号[重复]

jk9hmnmh  于 2023-03-28  发布在  Mysql
关注(0)|答案(2)|浏览(132)

此问题在此处已有答案

Defining Composite Key with Auto Increment in MySQL(7个答案)
昨天关门了。
我是一个初学者在SQL和我试图寻找一个答案没有任何运气。
我希望自动生成发票编号,并具有以下区别:

  • 我有2个不同的结构发票
  • 我想避免任何编号问题,例如,如果更改了某些内容(例如:1、2、4、5、8、9 ...)
  • 我希望它们每年都被重置,因此每个结构的编号每年都从1开始:

例如:ENG_2022_1、ENG_2022_2…ENG_2023_1
例如:FR_2022_1、FR_2022_2、FR_2022_3、... FR_2023_1
我曾想过设置一个自动递增的字段,但除非有解决方案,否则这对结构和年份的区别不起作用?
另一种解决方案是在开票前获取年份和结构,并将其与发票编号的SQL MAX进行比较,但我不确定该解决方案有多好?
任何帮助都将不胜感激

9w11ddsr

9w11ddsr1#

使用自动递增列似乎是显而易见的,但是,在您的情况下,您希望在每年年初重新开始编号,因此应该有一些东西可以适应这种情况。
我将在invoice表中为此创建至少四列:

***invoice_id:**这是自动递增列。
***invoice_date:**从该日期开始,您可以使用YEAR(invoice_date)获取年份。
*invoice_sequence:FRENG
***invoice_number:**包含实际发票号。

要创建发票编号,您需要知道当前年度序列中的发票数量。可以在单独的查询中检索:

SELECT
  COUNT(*) AS invoice_count
FROM
  invoice_table
WHERE
  invoice_sequence = :sequence AND
  YEAR(invoice_date) = YEAR(:date);

在这个查询中,:sequence:date是您要查找的binding the values的占位符。
之后,您可以插入实际发票。下面是这样一个插入的模型:

INSERT INTO
  invoice_table
  (invoice_date,
   invoice_sequence,
   invoice_number,
   ......)
VALUES
  (:date,
   :sequence, 
   CONCAT(:sequence, '_', YEAR(:date), '_', :invoiceCount),
   ......)

在这个查询中,:date:sequence:invoiceCountbinding the values的占位符。注意,在某些情况下,不能重复相同的占位符名称。在这种情况下,可以使用类似:name1:name2的名称,或者只使用?
请注意,您可以将用于检索插入查询中的计数的查询作为子查询。

nafvub8i

nafvub8i2#

我建议你分别存储序列、年份和数字。
为此,创建三个列:

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来获取指定序列和年份的前一个号码的最大值,以考虑发票删除的可能性,避免违反号码唯一性。

相关问题