'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
emailcolumnCREATE 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
intcolumnemail_idwhere required Update your data with the
idvalue 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
emailcolumn- Add a foreign key where
email_idreferencesemails(id)
- Add a new
When displaying your data and you need a zero-padded email
id, join theemailstable, 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
emailsfirst, then use the generatedidin 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 |
