1

I have a table and want to add another field identity

id | name | identity
 1 |  sam | 
 2 |  joe | 
 3 |  jen |

Right now there is no data for identity. I will have a string of 5 random character (ex: kdU3k) populate each row.

What is the best way to alter/update the table in this manner?


Since I have a PHP backend, I could technically loop through a SQL statement where identity = null, but I want to know how to do this with just SQL.

6
  • So I will have to write a PHP script? There's no way to do this with raw SQL? Commented Sep 11, 2014 at 0:13
  • Just use (SELECT UUID()) for the identity. Take last 5 characters from UUID() Commented Sep 11, 2014 at 0:22
  • @cha Such is not guaranteed to be unique, but it can definitely be used as a basis. Commented Sep 11, 2014 at 0:23
  • create a unique index on the column, and if it fails-retry Commented Sep 11, 2014 at 0:23
  • Something like create unique index asdf on users (identity) ? Commented Sep 11, 2014 at 0:40

1 Answer 1

4

While I do not recommend doing this, primarily because MySQL makes certain aspects less fun, this can be done entirely in MySQL DML without even the use of user-defined procedures. Procedures would allow the use of procedural while loops, etc.

I've created an sqlfiddle. The first step is to create the random values; in this case they are also ensured to be distinct in the table afterwards, which ensures there is one less thing to worry about.

-- Create lots of random values without using a proceure and loop.
-- There may be duplicates created. Could be a temporary table.
-- Would be much simplified if there was already a numbers table.
create table idents (value char(5));
insert into idents (value) values (left(md5(rand()), 5));               -- 1
insert into idents (value) select (left(md5(rand()), 5)) from idents;   -- 2
insert into idents (value) select (left(md5(rand()), 5)) from idents;   -- 4
insert into idents (value) select (left(md5(rand()), 5)) from idents;
insert into idents (value) select (left(md5(rand()), 5)) from idents;
insert into idents (value) select (left(md5(rand()), 5)) from idents;
insert into idents (value) select (left(md5(rand()), 5)) from idents;   -- 64

-- Delete duplicate values. While there may be a rare duplicate we will
-- still be left with a good many random values. A similar process
-- could also be used to weed out existing used values.
delete from idents
where value in (
  -- The select * is for another MySQL quirk
  select value from (select * from idents) i
  group by value
  having count(value) > 1);

Then the random values have to be associated with each person. This is done with a horrid simulation of a "ROW_NUMBER" on derived relations and a join.

set @a = 0;
set @b = 0;

-- Now here is UGLY MYSQL MAGIC, where variables are used to simulate
-- ROW_NUMBER. YMMV, it "Works Here, Now". Note the very suspicious
-- hack to assign @b back to 0 "for each" joined item.
update people p2
  join (select p.id, i.value
    -- Give each person record a row number
    from (select @a := @a + 1 as rn1, id, @b := 0 as hack from people) p
    -- Give each random number a row number
    join (select @b := @b + 1 as rn2, value from idents) i
    -- And join on row number
    on p.rn1 = i.rn2) pv
  on p2.id = pv.id
set p2.identity = pv.value

Again, YMMV.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.