MySQL Generate Random Data - mysql

In MySQL I have some tables I need to randomize the phone numbers and Email addresses to be randomly generated for development purposes.
In MySQL how could I generate 7 digit unique random numbers for the phone numbers?
How can I generate random email address like 545165498#mailinator.com.
How can I generate this random data with MySQL Queries?

MySQL rand() Returns a random floating-point value in the range 0 <= value < 1.0.
Multiply that by another number: UPPER_BOUND and get the floor of that, and you will get a random integer between 0 and (UPPER_BOUND-1) like this:
SELECT floor(rand() * 10) as randNum;
That will give you only one random number between 0 and 10.
Change the 10 to the number one higher than you want to generate.
Something like this :
UPDATE user
SET email = CONCAT(FLOOR(rand() * 10000000),'#mailinator.com'),
PhoneNo = FLOOR(rand() * 10000000)

This should give you a random number of 7 digits length
SELECT FLOOR(1000000 + RAND() * 8999999)
And something like this should update your phone numbers and e-mail addresses according to your requirement
UPDATE Customers
SET phone = CAST(FLOOR(1000000 + RAND(8999999) AS VARCHAR),
email = CONCAT(CAST(FLOOR(1000000 + RAND(8999999) AS VARCHAR), '#mailinator.com')

MySQL Generate random data walkthrough:
Random number between 0 (inclusive) and 1 exclusive:
mysql> select rand();
+--------------------+
| rand() |
+--------------------+
| 0.5485130739850114 |
+--------------------+
1 row in set (0.00 sec)
Random int between 0 (inclusive) and 10 exclusive:
mysql> select floor(rand()*10);
+------------------+
| floor(rand()*10) |
+------------------+
| 6 |
+------------------+
1 row in set (0.00 sec)
Random letter or number:
mysql> select concat(substring('ABCDEF012345', rand()*36+1, 1));
+---------------------------------------------------------------------------+
| concat(substring('ABCDEF012345', rand()*36+1, 1)) |
+---------------------------------------------------------------------------+
| F |
+---------------------------------------------------------------------------+
1 row in set (0.00 sec)
Random letter a to z:
mysql> select char(round(rand()*25)+97);
+---------------------------+
| char(round(rand()*25)+97) |
+---------------------------+
| s |
+---------------------------+
1 row in set (0.00 sec)
Random 8 character alphanumeric string:
mysql> SELECT LEFT(UUID(), 8);
+-----------------+
| LEFT(UUID(), 8) |
+-----------------+
| c26117af |
+-----------------+
1 row in set (0.00 sec)
Random capital letter in MySQL:
mysql> select CHAR( FLOOR(65 + (RAND() * 25)));
+----------------------------------+
| CHAR( FLOOR(65 + (RAND() * 25))) |
+----------------------------------+
| B |
+----------------------------------+
1 row in set (0.00 sec)
Load a random row into a table:
mysql> create table penguin (id INT primary key auto_increment, msg TEXT);
Query OK, 0 rows affected (0.02 sec)
mysql> insert into penguin values (0, LEFT(UUID(), 8));
Query OK, 1 row affected (0.00 sec)
mysql> select * from penguin;
+------+----------+
| id | msg |
+------+----------+
| 0 | abab341b |
+------+----------+
1 row in set (0.00 sec)
Load random rows:
Make a procedure called dennis that loads 1000 random rows into penguin.
mysql> delimiter ;;
mysql> drop procedure if exists dennis;;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> create procedure dennis()
-> begin
-> DECLARE int_val INT DEFAULT 0;
-> myloop : LOOP
-> if (int_val = 1000) THEN
-> LEAVE myloop;
-> end if;
-> insert into penguin values (0, LEFT(UUID(), 8));
-> set int_val = int_val +1;
-> end loop;
-> end;;
Query OK, 0 rows affected (0.00 sec)
mysql> call dennis();;
mysql> select * from penguin;;
+------+----------+
| id | msg |
+------+----------+
| 0 | abab341b |
| 1 | c5dc08ee |
| 2 | c5dca476 |
...
+------+----------+
Update all rows in a table to have random data:
mysql> create table foo (id INT primary key auto_increment, msg TEXT);
Query OK, 0 rows affected (0.02 sec)
mysql> insert into foo values (0,'hi');
Query OK, 1 row affected (0.00 sec)
mysql> insert into foo values (0,'hi2');
Query OK, 1 row affected (0.00 sec)
mysql> insert into foo values (0,'hi3');
Query OK, 1 row affected (0.00 sec)
mysql> select * from foo;
+----+------+
| id | msg |
+----+------+
| 1 | hi |
| 2 | hi2 |
| 3 | hi3 |
+----+------+
3 rows in set (0.00 sec)
mysql> update foo set msg = rand();
Query OK, 3 rows affected (0.00 sec)
Rows matched: 3 Changed: 3 Warnings: 0
mysql> select * from foo;
+----+---------------------+
| id | msg |
+----+---------------------+
| 1 | 0.42576668451145916 |
| 2 | 0.6385560879842901 |
| 3 | 0.9154804171207178 |
+----+---------------------+
3 rows in set (0.00 sec)

Here is an online tool to generate random data with many options. http://www.generatedata.com/
Just enter the parameters to define what kind of random data you want, and export it to the appropriate format, then you can load it.

Related

Search for a text containing backslash in MySQL

I have a mysql table with 2 entries (id ,title) (int, text)
A row of dummy data in the table looks like
id title
1 apple\"apple
My query intends to do a search on the field title
select * from table1 where title='apple\"apple';
I also tried using
select * from table1 where title like('apple\"apple');
The above query did not seem to work as well.
Both queries are returning an empty sets. Is it not possible to search for a string that has backslash in it?
PS :: The \ is added to the DB as part of escaping the double quotes.
Sure? It works as expected.
mysql> CREATE TABLE MyTbl (id INT, title TEXT);
Query OK, 0 rows affected (0.01 sec)
mysql> INSERT INTO MyTbl VALUES(1,'apple "apple');
Query OK, 1 row affected (0.00 sec)
mysql> SELECT * FROM MyTbl;
+------+-------------+
| id | title |
+------+-------------+
| 1 | apple"apple |
+------+-------------+
1 row in set (0.00 sec)
mysql> SELECT * FROM MyTbl WHERE title = 'apple \"apple';
+------+-------------+
| id | title |
+------+-------------+
| 1 | apple"apple |
+------+-------------+
1 row in set (0.00 sec)
mysql> SELECT * FROM MyTbl WHERE title like('apple \"apple');
+------+-------------+
| id | title |
+------+-------------+
| 1 | apple"apple |
+------+-------------+
1 row in set (0.00 sec)
Maybe Is it something related to the space character?
mysql> SELECT * FROM MyTbl WHERE title = 'apple\"apple';
Empty set (0.00 sec)
mysql> SELECT * FROM MyTbl WHERE title = 'apple \"apple';
+------+--------------+
| id | title |
+------+--------------+
| 1 | apple "apple |
+------+--------------+
1 row in set (0.00 sec)
What about running this command? What It returns for you?
mysql> SELECT #NO_BACKSLASH_ESCAPES;
+----------------------------------------------+
| #NO_BACKSLASH_ESCAPES |
+----------------------------------------------+
| NULL |
+----------------------------------------------+
1 row in set (0.00 sec)

what syntax to use to update a SET column in mysql?

I created a column called oilcompany that has SET data (Hunt, Pioneer, Chevron, BP)
I can enter any one of those into the oilcompany column and change from one to another one but I can not figure out how to change from one oilcompany to multiple oilcompany (eg. Hunt and BP)... any suggestion?
In the MySQL documentation there are not examples for UPDATE statements, but I normally use two ways to update these kind of columns:
Using text values
Using numeric values
Creating the test environment
mysql> CREATE TABLE tmp_table(
-> id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
-> oilcompany SET('Hunt', 'Pioneer', 'Chevron', 'BP')
-> );
Query OK, 0 rows affected (0.54 sec)
mysql> INSERT INTO tmp_table(oilcompany) VALUES ('Hunt'), ('Pioneer');
Query OK, 2 rows affected (0.11 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> SELECT * FROM tmp_table;
+----+------------+
| id | oilcompany |
+----+------------+
| 1 | Hunt |
| 2 | Pioneer |
+----+------------+
2 rows in set (0.00 sec)
Alternative#1: Using Text Values
As a SET is a collection of ENUM elements, and any ENUM element can be treated as a string, then we can do things like:
mysql> UPDATE tmp_table
-> SET oilcompany = 'Hunt,BP'
-> WHERE id = 1;
Query OK, 1 row affected (0.07 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> SELECT * FROM tmp_table;
+----+------------+
| id | oilcompany |
+----+------------+
| 1 | Hunt,BP |
| 2 | Pioneer |
+----+------------+
2 rows in set (0.00 sec)
Alternative#2: Using Numeric Values
Any SET element is stored internally as a 64bit number containing the combination of the bits that represent each SET element.
In our table: 'Hunt'=1, 'Pioneer'=2, 'Chevron'=4, 'BP'=8.
Also, mysql allows to use these numbers instead of text values. If we need to see the numeric value in the select, we need to use the SET column inside a numeric expression (E.g. adding zero).
Let's see the current values:
mysql> SELECT id, oilcompany+0, oilcompany FROM tmp_table;
+----+--------------+------------+
| id | oilcompany+0 | oilcompany |
+----+--------------+------------+
| 1 | 9 | Hunt,BP |
| 2 | 2 | Pioneer |
+----+--------------+------------+
2 rows in set (0.00 sec)
Here 9 = 'Hunt' (1) + 'BP' (8) and 2 = 'Pioneer' (2).
Now, let's change the Pioneer to 'Hunt' (1) + 'Chevron' (4):
mysql> UPDATE tmp_table
-> SET oilcompany = 5
-> WHERE id = 2;
Query OK, 1 row affected (0.08 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> SELECT id, oilcompany+0, oilcompany FROM tmp_table;
+----+--------------+--------------+
| id | oilcompany+0 | oilcompany |
+----+--------------+--------------+
| 1 | 9 | Hunt,BP |
| 2 | 5 | Hunt,Chevron |
+----+--------------+--------------+
2 rows in set (0.00 sec)

Formatting a temporary table

I have created a temporary table with two fields, formatted to int.
create table #tmp
unprocessed int,
invoiced int
I am then calculating a third field with this.
select unprocessed, invoiced, (unprocessed /invoiced) as percentageunprocessed
from #tmp
My result is
Unprocessed invoiced percentageunprocessed
33 200 0
It should be
33 200 0.165
I think this is because the percentageunprocessed is also formatted as int and not dec (5,2). Can I change the format?
Its not the Answer:
it not normal. normal its return a float
my version
mysql> SELECT VERSION();
+-----------+
| VERSION() |
+-----------+
| 5.7.15 |
+-----------+
1 row in set (0,00 sec)
mysql>
sample
mysql> CREATE TEMPORARY TABLE result (a INT, b INT);
Query OK, 0 rows affected (0,00 sec)
mysql> INSERT INTO result VALUES(10,330);
Query OK, 1 row affected (0,00 sec)
mysql> SELECT a,b,a/b FROM result;
+------+------+--------+
| a | b | a/b |
+------+------+--------+
| 10 | 330 | 0.0303 |
+------+------+--------+
1 row in set (0,00 sec)
mysql>

mysql delete triggers

I think I read that the delete trigger doesn't know what data was deleted and loops over the whole table applying the trigger. Is that true?
Does that mean that the before delete loops over the whole table before the data is deleted and after delete loops over the whole table after the delete occurs?
Is there no way to loop over just the deleted records? So If 10 records are deleted loop over them?
DELIMITER $$
DROP TRIGGER `before_delete_jecki_triggername`$$
CREATE TRIGGER before_delete_triggername
BEFORE DELETE ON table
FOR EACH ROW
BEGIN
/*do stuff*/
END$$
DELIMITER ;
Thanks,
Mat
I think it was due to a confusion with FOR EACH ROW statement.
It is only for "matched records for the statement issued before trigger is invoked."
If there exists N number of records in a table and matches records for where id=x,
assuming x causes a result of less than N records, say N-5, then
FOR EACH ROW causes a loop for N-5 times only.
UPDATE:
A sample test run on the rows affected due to FOR EACH ROW statement is shown below.
mysql> -- create a test table
mysql> drop table if exists tbl; create table tbl ( i int, v varchar(10) );
Query OK, 0 rows affected (0.01 sec)
Query OK, 0 rows affected (0.06 sec)
mysql> -- set test data
mysql> insert into tbl values(1,'one'),(2,'two' ),(3,'three'),(10,'ten'),(11,'eleven');
Query OK, 5 rows affected (0.02 sec)
Records: 5 Duplicates: 0 Warnings: 0
mysql> select * from tbl;
+------+--------+
| i | v |
+------+--------+
| 1 | one |
| 2 | two |
| 3 | three |
| 10 | ten |
| 11 | eleven |
+------+--------+
5 rows in set (0.02 sec)
mysql> select count(*) row_count from tbl;
+-----------+
| row_count |
+-----------+
| 5 |
+-----------+
1 row in set (0.00 sec)
mysql>
mysql> -- record loop count of trigger in a table
mysql> drop table if exists rows_affected; create table rows_affected( i int );
Query OK, 0 rows affected (0.02 sec)
Query OK, 0 rows affected (0.05 sec)
mysql> select count(*) 'rows_affected' from rows_affected;
+---------------+
| rows_affected |
+---------------+
| 0 |
+---------------+
1 row in set (0.00 sec)
mysql>
mysql> set #cnt=0;
Query OK, 0 rows affected (0.00 sec)
mysql>
mysql> -- drop trigger if exists trig_bef_del_on_tbl;
mysql> delimiter //
mysql> create trigger trig_bef_del_on_tbl before delete on tbl
-> for each row begin
-> set #cnt = if(#cnt is null, 1, (#cnt+1));
->
-> /* for cross checking save loop count */
-> insert into rows_affected values ( #cnt );
-> end;
-> //
Query OK, 0 rows affected (0.00 sec)
mysql>
mysql> delimiter ;
mysql>
mysql> -- now let us test the delete operation
mysql> delete from tbl where i like '%1%';
Query OK, 3 rows affected (0.02 sec)
mysql>
mysql> -- now let us see what the loop count was
mysql> select #cnt as 'cnt';
+------+
| cnt |
+------+
| 3 |
+------+
1 row in set (0.00 sec)
mysql>
mysql> -- now let us see the table data
mysql> select * from tbl;
+------+-------+
| i | v |
+------+-------+
| 2 | two |
| 3 | three |
+------+-------+
2 rows in set (0.00 sec)
mysql> select count(*) row_count from tbl;
+-----------+
| row_count |
+-----------+
| 2 |
+-----------+
1 row in set (0.00 sec)
mysql> select count(*) 'rows_affected' from rows_affected;
+---------------+
| rows_affected |
+---------------+
| 3 |
+---------------+
1 row in set (0.00 sec)
mysql>

using a mysql trigger to copy and paste value within the same row, is it possible?

I have a form in which the user enters their e-mail address along with their username and desired password. How would I go about creating a trigger that will copy the e-mail address into the username field (located in the same row) if the user doesn't select a user name?
Table: Users
+-------+---------+------+-----+---------+
| uName | uPassword | uEmail |
+-------+---------+------+-----+---------+
| NULL | pass123 | uzr#sql.com |
+-------+---------+------+-----+---------+
Are you sure you need a trigger to do that? If you have control over your insert or update statement (which you may not if you're using an ORM) you can do something like this:
mysql> insert into t4 (uemail, upassword, uname) SELECT #email:='joe#joe.com', 'secretpassword', ifnull(null, #email);
Query OK, 1 row affected (0.00 sec)
Records: 1 Duplicates: 0 Warnings: 0
mysql> select * from t4 where uemail='joe#joe.com';
+-------------+----------------+-------------+
| uname | upassword | uemail |
+-------------+----------------+-------------+
| joe#joe.com | secretpassword | joe#joe.com |
+-------------+----------------+-------------+
1 row in set (0.00 sec)
If you don't have control over the insert/update statements, then yes, you can use a trigger for that:
mysql> create trigger setuname before insert on t4
-> for each row begin
-> set new.uname=ifnull(new.uname, new.uemail);
-> end;
-> |
Query OK, 0 rows affected (0.09 sec)
mysql> delimiter ;
mysql> insert into t4 (uname, uemail, upassword) values (null, 'joe#joe.com', 'secretpassword');
Query OK, 1 row affected (0.00 sec)
mysql> select * from t4;
+-------------+----------------+-------------+
| uname | upassword | uemail |
+-------------+----------------+-------------+
| joe#joe.com | secretpassword | joe#joe.com |
+-------------+----------------+-------------+
1 row in set (0.00 sec)