'MYSQL: Create Unique ID based on Another Column
If I have the following column in database:
Email
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
I would like to ALTER THE TABLE and create a unique ID column based on the 'Email' column. Like the following:
Email Email_ID
[email protected] 001
[email protected] 002
[email protected] 003
[email protected] 002
[email protected] 004
[email protected] 001
Solution 1:[1]
I would suggest that you use an integer for the value -- rather than a string. Then, you can use variables as for the assignment:
alter table t add email_id int;
update t join
(select email, (@rn := @rn + 1) as rn
from (select distinct email from t order by email) t cross join
(select @rn := 0) params
) tt
on t.email = tt.email
set t.email_id = tt.rn;
If you run the subquery, you will see that this assigns to each email a distinct number.
The outer query then assigned this number into the email_id
column. In MySQL 8+, you could also write:
alter table t add email_id int;
update t join
(select email, row_number() over (order by email) as rn
from (select distinct email from t order by email) t
) tt
on t.email = tt.email
set t.email_id = tt.rn;
Solution 2:[2]
If you are using MySQL version 8 or later, then DENSE_RANK
provides a nice option here:
SELECT
Email,
LPAD(CAST(DENSE_RANK() OVER (ORDER BY Email) AS CHAR(3)), 3, '0') AS Email_ID
FROM yourTable
ORDER BY
Email;
I would have suggested maybe just adding an auto increment column to your table, but that wouldn't quite meet your requirements, because an auto increment column would always be unique.
Solution 3:[3]
Here's what I'd do...
Create a new table with a unique
email
columnCREATE TABLE `emails` ( id INT(3) PRIMARY KEY AUTO_INCREMENT, email VARCHAR(255) UNIQUE );
Seed it with your current data
INSERT INTO `emails` (`email`) SELECT DISTINCT `email` FROM `some_mystery_table` ORDER BY `email`;
Alter your existing tables to reference
emails(id)
as a foreign key. This could be a little tricky as you'd need to (probably)- Add a new
int
columnemail_id
where required Update your data with the
id
value corresponding to the email addressUPDATE some_mystery_table, emails INNER JOIN emails ON some_mystery_table.email = emails.email SET some_mystery_table.email_id = emails.id;
Remove the
email
column- Add a foreign key where
email_id
referencesemails(id)
- Add a new
When displaying your data and you need a zero-padded email
id
, join theemails
table, egSELECT a.whatever, e.email, LPAD(e.id, 3, '0') AS email_id FROM some_mystery_table a INNER JOIN emails e ON a.email_id = e.id;
When adding new email records, you add them to
emails
first, then use the generatedid
in any other related tables.
Solution 4:[4]
ALTER TABLE emails add column `email_id` int(5) ZEROFILL PRIMARY KEY AUTO_INCREMENT;
SET @x:=0;
UPDATE emails SET email_id = LPAD(@x:= (@x+1),4, '0') WHERE 1=1;
We first added the column email_id
to the table emails
and set it as primary key, using this query:
ALTER TABLE emails add column `email_id` int(5) ZEROFILL PRIMARY KEY AUTO_INCREMENT;
Then we declared a global variable called x with a default value of 0:
SET @x:=0;
And finally, we filled the column with the incremental zero filled id:
UPDATE emails SET email_id = LPAD(@x:= (@x+1),4, '0') WHERE 1=1;
We used LPAD to zero fill.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | |
Solution 3 | |
Solution 4 |