mysql auto increment from 00001 - 99999 and reset the value every year - mysql

My first aim is to generate customer reference code automaticaly everytime when I insert a new customer
so when it shown in my nodejs it should be : "MS2200001"
So my idea is set id from customer table (mysql) with auto increment and zerofill (int)
length = 5
So I can get id 00001
and insert to another column named as "customer reference"
with
("MS" + (2022)+ "00001")
And I am trying to reset the counter to 00001 again if become 2023,2024,2025 etc.
How can I archive this in phpmyadmin or I should chnage my idea?

Use trigger-generating technique and additional MyISAM table with secondary AUTO_INCREMENT column in PRIMARY KEY.
An example:
-- base table for complete identifier generation
CREATE TABLE base_for_complete_id (
`year` YEAR,
id INT AUTO_INCREMENT,
PRIMARY KEY (`year`, id)
) ENGINE = MyISAM;
-- create trigger which will generate complete identifier
CREATE TRIGGER generate_complete_id
BEFORE INSERT ON maintable
FOR EACH ROW
BEGIN
DECLARE tmp INT;
-- insert row into base table
INSERT INTO base_for_complete_id (`year`) VALUES (YEAR(NEW.created_at));
-- store id generated for current year
SET tmp = LAST_INSERT_ID();
-- save generated complete identifier into main table
SET NEW.complete_id = CONCAT('prefix_', YEAR(NEW.created_at), '_', tmp);
-- clear excess rows from base table
DELETE FROM base_for_complete_id WHERE `year` = YEAR(NEW.created_at) AND id < tmp;
END
DEMO fiddle
If you need to format id part of generated value with leading zeros then use LPAD() function, for example SET tmp = LPAD(LAST_INSERT_ID(), 5, 0);.
Caution! If the value for generated number exceeds 99999 then it will be truncated, and only 5 leading digits will be stored.

Related

Insert and fill a non restricted field with the new unique key autoincrement id value

I have a table with two fields:
Unique Id autoincrement -> Id
int -> copyOfId
Id can be written manually, or can be assigned by database but copyOfId.
To set the same value to Id and copyOfId, I can do this:
set #nextId = (select id from table order by id desc limit 1) + 1;
insert into table (Id,...,...,...,copyOfId,...,...,...
) VALUES (
#nextId,...,...,...,#nextId,...,...,...);
Is it possible to set the copyOfId with the same Id on an Insert automatically?
Is it possible to set the copyOfId with the same Id on an Insert automatically?
No. Neither BEFORE trigger nor generated column may refer to autoincremented column.
But you may remove autoincrementing, create separate table with autoincremented column, and set both id and its copy from BEFORE trigger.
Example fiddle with some explanations.
Pay attention - the values for id and its copy provided in INSERT will be overwritten unconditionally. If you need to set them manually to some N then insert a row with N-1 value (which must be above current maximal value) into additional table explicitly then insert into working table.
Do not update PK value in working table with the value above current maximal value.

How do I change the auto increment counter in MySQL from +1 to +43

I am trying to change the auto increment counter in MySQL from +1 to +43.
For example my rows have Id = 1, 2, 3.
But I don’t want the Id’s having +1 sequence.
I want them like 43, 86, 129
I tried
ALTER TABLE `table_name` AUTO_INCREMENT=43
But this just changed the sequence to 43, 44, 45
You have to change the system variable auto_increment_offset to the offset you want. But be careful using this solution since you change the offset for all tables (and INSERT commands). I don't recommend this solution, another column with a custom (calculated) ID would be a better solution:
SET ##session.auto_increment_offset = 43;
INSERT INTO table_name (col1, col2) VALUES ('val1', 'val2')
You can also use the default auto increment (offset = 1) and using a calculation to get the custom increment:
SELECT id, id * 43 AS `custom_id`
FROM table_name
Answer from Mark S. Rasmussen's blog: https://improve.dk/working-with-identity-column-seed-and-increment-values/
Changing the identity increment value
Unfortunately there’s no easy way to change the increment value of an identity column. The only way to do so is to drop the identity column and add a new column with the new increment value. The following code will create a new temporary table, copy the data into it, recreate the original table with the correct increment value and then finally copy the data back using SET IDENTITY_INSERT ON.aspx) to insert explicit values into the identity column.
BEGIN TRAN
-- Create new temporary table to hold data while restructuring tblCars
CREATE TABLE tblCars_TMP
(
CarID int NOT NULL,
Name nvarchar(50) NOT NULL
)
-- Insert tblCars data into tblCars_TMP
INSERT INTO tblCars_TMP SELECT * FROM tblCars
-- Drop original table
DROP TABLE tblCars
-- Create new tblCars table with correct identity values (1,1) in this case
CREATE TABLE [dbo].[tblCars]
(
[CarID] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](50) NOT NULL,
)
-- Reinsert data into tblCars table
SET IDENTITY_INSERT tblCars ON
INSERT INTO tblCars (CarID, Name) SELECT CarID, Name FROM tblCars_TMP
SET IDENTITY_INSERT tblCars OFF
COMMIT

SQL Trigger: New row :tableA to new col in :tableB

I have a database with a couple of tables. I need to add a column in one table after the insertion of a new row in another table.
Table A: id | Type | Category | ShortDesc | LongDesc | Active
Row 1 int(11), varchar, varchar,varchar,varchar,int
Row 2
Row 3
Table B: id | Row1-ShortDesc | Row2-ShortDesc | Row3-ShortDesc
Row 1 int(11), tiny(1), tiny(1), tiny(1) etc...
Row 2
Row 3
When I occasionally add a new row (item) to TableA, I want a new column in TableB. TableA is a long evolving collection. A Row in TableA can not be removed for obvious legacy reasons.
So when I insert a row to TableA I need to have another column inserted/appended into TableB.
Any help would be appreciated.
TIA.
Answer derived from training in SQL
I was finally able to derive and create my trigger solution utilizing a class in SQL Server at MAX TRAINING in CINCINNATI OHIO.
--SQL CODE
-- Create a table called TableA that just holds some data for the trigger
-- This table has a primary Key seeded with 1 and incremented by 1
CREATE TABLE TableA(
id int identity(1,1) PRIMARY KEY,
name varchar(60) NOT NULL,
shortDesc varchar(60) NOT NULL,
longDesc varchar(60) NOT NULL,
bigDesc TEXT NOT NULL
)
GO
-- Create a table TableB that only has a ID column. ID as a primary key seeded with 1, incremented by 1
CREATE TABLE TableB(
id int identity(1,1) PRIMARY KEY
)
GO
-- Just to see the two tables with nothing in it.
select * from TableA
select * from TableB
GO
-- The actual trigger in TableA based upon an insert
CREATE TRIGGER TR_myInserCol
ON TableA
AFTER INSERT
AS
BEGIN
-- Don't count the trigger events
SET NOCOUNT ON;
-- Because we are making strings we declare some variables
DECLARE #newcol as varchar(60);
DECLARE #lastRow as int;
DECLARE #sql as varchar(MAX);
-- Now fill the variables
-- make sure we are looking at the last, freshly inserted row
SET #lastRow = (SELECT COUNT(*) FROM TableA);
-- Make a SELECT statement for the last row
SET #newcol = (SELECT shortDesc FROM TableA WHERE id = #lastRow);
-- Adds a new column in TableB is inserted based on a
-- TableA.shortDesc as the name of the new column.
-- You can use any row data you want but spaces and
-- special characters will require quotes around the field.
SET #sql = ('ALTER TABLE TableB ADD ' + #newcol + ' char(99)');
-- And run the SQL statement as a combined string
exec(#sql);
END;
GO
--Insert a new rows into TableA
--The trigger will fire and add a column in TableB
INSERT INTO TableA
(name,shortDesc,longDesc,bigDesc)
VALUES ('attract','Attraction','Attractions','Places to go see and have
fun');
GO
INSERT INTO TableA
(name,shortDesc,longDesc,bigDesc)
VALUES ('camp','Camp','CAMP GROUND','Great place to sleep next to a creek');
GO
(name,shortDesc,longDesc,bigDesc)
VALUES ('fuel','GasStation','Fueling Depot','Get gas and go');
GO
INSERT INTO TableA
(name,shortDesc,longDesc,bigDesc)
VALUES ('petstore','PetStore','Pet Store','Get a friend');
GO
-- See the newly created rows in TableA and the new Columns created in TableB
select * from TableA
select * from TableB
GO
-- Do not execute unless you want to delete the newly created tables.
-- Use this to delete your tables
-- Clean up your work space so you can make changes and try again.
DROP TABLE TableA;
DROP TABLE TableB;
GO
Thanks again to those that tried to help me out. And yes, I still understand this may not be the best solution but for me this works as I will only insert rows in TableA maybe a couple of times a year and will more than likely max out with less than 300 rows over the next several years as the data I am working with doesn't change that frequently and have a single row to access with a single bit (T/F) allows me to now quickly assign TableB's to locations and people for their search criteria and to generate a nice SQL query string without multiple reads across potentially several pages. Thanks again!
And if someone wants to add or modify what I have done, I'm all ears. It's all about learning and sharing.
Michael

mysql insert with value equal to primary key + 1

I have an auto increment column ID, and for some situation I wanted the other column to be equal to the primary key + 1 value
ID | other
1 | 2
2 | 3
3 | 4
4 | 123 (some situation, it is not always plus 1)
How can I achieve this?
Here's what I have tried
INSERT INTO table (`ID`,`other`) VALUES ('',(SELECT MAX(ID)+1 FROM table))
But that returns an error
You can't specify target table 'table' for update in FROM clause
Try Below query:
ALTER TABLE dbo.table ADD
Column AS ([ID]+1)
GO
It will definitely work
Using a normal AUTO_INCREMENT column as id, I cannot think of a way to do this in MySQL. Triggers, which otherwise would have been an option, don't work well with AUTO_INCREMENT columns.
The only way I see is to do two commands for an INSERT;
INSERT INTO bop (value) VALUES ('These values should be 1 and 2');
UPDATE bop SET other = id+1 WHERE id = LAST_INSERT_ID();
An SQLfiddle to test with.
The closest I'm getting to what you're looking for is to generate sequences separately from AUTO_INCREMENT using a function, and use that instead to generate the table id;
DELIMITER //
CREATE TABLE bop (
id INT UNIQUE,
other INT,
value VARCHAR(64)
)//
CREATE TABLE bop_seq ( seq INT ) // -- Sequence table
INSERT INTO bop_seq VALUES (1) // -- Start value
CREATE FUNCTION bop_nextval() RETURNS int
BEGIN
SET #tmp = (SELECT seq FROM bop_seq FOR UPDATE);
UPDATE bop_seq SET seq = seq + 1;
RETURN #tmp;
END//
CREATE TRIGGER bop_auto BEFORE INSERT ON bop
FOR EACH ROW
SET NEW.id = bop_nextval(), NEW.other=NEW.id + 1;
//
That'd let you do inserts and have it autonumber like you want. The FOR UPDATE should keep the sequence transaction safe, but I've not load tested so you may want to do that.
Another SQLfiddle.
I solved this by updating 2 times the DB..
I wanted to do +1 from 19 till ..
UPDATE `table` SET `id`=`id`+101 WHERE id <= 19
UPDATE `table` SET `id`=`id`-100 WHERE id <= 119 AND id >= 101

remove gaps in auto increment

Say I have a MySQL table with an auto incrementing id field, then I insert 3 rows. Then, I delete the second row. Now the id's of the table go 1,3. Can I get MySQL to correct that and make it 1,2 without having to write a program to do so?
MySQL won't let you change the indexing of an Auto-Index column once it's created. What I do is delete the Auto-Index column and then add a new one with the same name, mysql will index the newly generated column with no gaps. Only do this on tables where the Auto-Index is not relevant to the rest of the data but merely used as a reference for updates and deletes.
For example I recently did just that for a table containing proverbs where the Auto-Index column was only used when I updated or deleted a proverb but I needed the Auto-Index to be sequential as the proverbs are pulled out via a random number between 1 and the count of the proverbs, having gaps in the sequence could have led to the random number pointing to a non-existant index.
HTH
Quoting from The Access Ten Commandments (and it can be extensible to other RDBMS: "Thou shalt not use Autonumber (or Auto Incremental) if the field is meant to have meaning for thy users".
The only alternative I can think of (using only MySQL) is to:
Create a trigger that adds the row number to a column (not the primary key)
Create a procedure to delete rows and update the row number (I couldn't make this work with triggers, sorry)
Example:
create table tbl_dummy(
id int unsigned not null auto_increment primary key,
row_number int unsigned not null default 0,
some_value varchar(100)
);
delimiter $$
-- This trigger will add the correct row number for each record inserted
-- to the table, regardless of the value of the primary key
create trigger add_row_number before insert on tbl_dummy
for each row
begin
declare n int unsigned default 0;
set n = (select count(*) from tbl_dummy);
set NEW.row_number = n+1;
end $$
-- This procedure will update the row numbers for the records stored
-- after the id of the soon-to-be-deleted record, and then deletes it.
create procedure delete_row_from_dummy(row_id int unsigned)
begin
if (select exists (select * from tbl_dummy where id = row_id)) then
update tbl_dummy set row_number = row_number - 1 where id > row_id;
delete from tbl_dummy where id = row_id;
end if;
end $$
delimiter ;
Notice that you'll be forced to delete the records one by one, and you'll be forced to get the correct primary key value of the record you want to delete.
Hope this helps