Мне нужно создать несколько таблиц, которые смогут автоматически увеличивать уникальные имена документов для каждого месяца года в зависимости от даты каждого типа документа. Я думаю, что было бы неплохо сделать это как сгенерированный сохраненный столбец в таблице MySql. В Таиланде используется буддийский календарь, в котором к христианскому календарю обычно добавляют 543 года (2024 год становится 2567). В данном случае я добавляю 43 года, поскольку мне нужны только последние цифры года. Затем мне не хватает последнего серийного номера, и я не могу найти решение после интенсивного поиска в Интернете. Я думаю, его следует найти в группе. В данном случае я работаю со счетами-фактурами.
Моя таблица:
CREATE TABLE `tbl_0_invoices` (
`invoice_date` date NOT NULL,
`invoice_no` varchar(45) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_520_ci GENERATED ALWAYS AS (concat(_utf8mb4'INV',(date_format(`invoice_date`,_utf8mb4'%y') + 43),date_format(`invoice_date`,_utf8mb4'%m'))) STORED;
ALTER TABLE `tbl_0_invoices`
ADD PRIMARY KEY (`invoice_no`);
Никакой документации по этому вопросу мне найти не удалось, даже такая идентификация документов вполне нормальна в Таиланде.
Я ожидаю такого вывода.
MyISAM позволил вам создать многостолбцовый первичный ключ с групповым автоматическим увеличением второго столбца. Эта функция недоступна в InnoDB. Возможно, вам придется делать то, что вы хотите, используя триггер INSERT.
Вы также не можете использовать триггер INSERT, поскольку значения автоприращения не генерируются в триггере BEFORE, но вы не можете изменять столбцы в триггере AFTER. Вы также не можете создать сгенерированное выражение столбца, которое ссылается на значение автоинкремента.
Будьте осторожны: в сильно параллельной среде это требование может вызвать узкие места.
@eric258 @eric258 Я не могу использовать серийный прирост, если он не сбрасывается каждый месяц. Требование от бухгалтерской компании, ведущей нашу отчетность.
@Barmar Спасибо, я попробовал это, заглянув в stackoverflow.com/questions/1600294/…, разница в том, что базовое поле (группа) также генерируется при вставке, а не выбранное значение, поэтому до сих пор нет успех.
Используйте DATE_FORMAT(date, "%y%m")
, чтобы получить числовой год и месяц в формате: YYMM
.
Используйте row_number() OVER (PARTITION BY date)
, чтобы получить значение приращения относительно значения YYMM
.
Итак, это простой запрос на соединение строк.
и запрос MySQL должен быть:
select
DATE_FORMAT(cast(invoice_date as date), '%d/%m/%Y') as invoice_date,
CONCAT("INV",
DATE_FORMAT(cast(invoice_date as date), "%y%m"),
"-",
row_number() OVER (PARTITION BY DATE_FORMAT(cast(invoice_date as date), "%y%m"))
) as invoice_no
from mySQLTable;
Результат проверки: db<>fiddle
Результат следующий:
Спасибо, все работает нормально. У меня один комментарий и один вопрос: 1. Вы не можете указать дату, потому что 29 февраля будет давать проблему каждые 4 года, поэтому к году добавляется только 43, что я и сделал. 2. Я не уверен, как реализовать это в своей таблице, но я всегда могу создать идентификатор счета и присоединиться к таблице с представлением, в этом ли идея?
Я не понимаю, чего именно вы хотите... Ваш вопрос решен согласно описанию и это новая проблема, тогда создайте отдельный тикет с соответствующей dbfiddle
таблицей данных @LasseStaalung
«Мне нужно создать несколько таблиц, которые смогут автоматически увеличивать уникальные имена документов для каждого месяца года в зависимости от даты каждого типа документа». Вы боретесь с типичным поведением автоматического увеличения, которое дает вам последовательно увеличивающееся значение. . Действительно ли прирост необходимо сбрасывать каждый месяц? Смогли бы вы жить с
INV-6708-1
,INV-6708-2
,INV-6709-3
, где серийный индекс не сбрасывается каждый месяц?