I want to populate a table with unique random numbers without using a procedure.
I've tried using this reply to do it but not success.
What I'm trying to do is something like this but validating that numbers are not repeated:
INSERT into table (row1,row2)
WITH RECURSIVE
cte AS ( SELECT 0 num, LPAD(FLOOR(RAND() * 99999999),8,0) random_num
UNION ALL
SELECT num+1, LPAD(FLOOR(RAND() * 99999999),8,0) random_num
FROM cte WHERE num < 100000-1)
SELECT random_num, null
FROM cte;
In the example above, I am able to generate random values and insert them but without validating that the numbers are not repeated.
I have tried to do this:
INSERT into table (row1,row2)
WITH RECURSIVE
cte AS ( SELECT 0 num, LPAD(FLOOR(RAND() * 99999999),8,0) random_num
UNION ALL
SELECT num+1, LPAD(FLOOR(RAND() * 99999999),8,0) random_num
FROM cte WHERE num < 100000-1 AND random_num NOT IN (SELECT random_num FROM cte WHERE random_num IS NOT NULL))
SELECT random_num, null
FROM cte;
but the condition AND random_num NOT IN (SELECT random_num FROM cte WHERE random_num IS NOT NULL) in the where case, causes an SQL Error [4008] [HY000]: Restrictions imposed on recursive definitions are violated for table 'cte'
Any suggestions of how to do it? thank you!.
This could be an option. Generate all possible values, sort randomly and take desired number of entries.
CREATE TABLE random_data (
row1 INT PRIMARY KEY AUTO_INCREMENT,
row2 VARCHAR(10) NOT NULL,
UNIQUE KEY _Idx1 ( row2 )
);
INSERT INTO random_data (row2)
SELECT LPAD(num, 8, 0)
FROM (
SELECT h * 10000000 + g * 1000000 + f * 100000 + e * 10000 + d * 1000 + c * 100 + b * 10 + a AS num
FROM (SELECT 0 a UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) ta
JOIN (SELECT 0 b UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) tb
JOIN (SELECT 0 c UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) tc
JOIN (SELECT 0 d UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) td
JOIN (SELECT 0 e UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) te
JOIN (SELECT 0 f UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) tf
JOIN (SELECT 0 g UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) tg
JOIN (SELECT 0 h UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) th
) n
ORDER BY RAND()
LIMIT 100000;
If you have a table - any table - with e.g. 100 rows then you can generate million distinct random numbers between 0 and 99999999 as follows:
select distinct floor(rand() * 100000000)
from t as t0, t as t1, t as t2
limit 1000000
Note that because of distinct you will need to generate a bigger number of rows so that you get desired number of rows after distinct.
Suppose I've Table T and It has 3 Columns and 3rd Column contains 10 distinct values and I want to fetch 5 samples from Table T for each distinct value in column 3rd.
WITH T(A, B,C) AS(
SELECT 12,'Hi','One' FROM DUAL UNION ALL
SELECT 34,'Am','One' FROM DUAL UNION ALL
SELECT 6,'to','Two' FROM DUAL UNION ALL
SELECT 3,'do','Two' FROM DUAL UNION ALL
SELECT 5,'aim','Two' FROM DUAL UNION ALL
SELECT 6,'mine','Two' FROM DUAL UNION ALL
SELECT 4,'not','Three' FROM DUAL
)
select a,b,c from(
SELECT A,B,C,ROW_NUMBER() OVER(PARTITION BY c ORDER BY C DESC) AS R
FROM T)
where r = 1
or you could possibly try this:
SELECT MIN(T.A),
T.B,
t.c
FROM t
JOIN (SELECT C,
MAX(b) AS b
FROM T
GROUP BY C) Y ON Y.C = T.C
AND Y.B = T.B
GROUP BY t.c, t.b
I have a list of user IDs, like this:
757392,733602,749955,744304,746852,753904,755117,636163,564931,740787,751450,743799,643918,
749903,571888,30207,705953,749120,749001,749192,749978,750840,544228,702121,746246,383667,
558790,585628,592771,745818,749375,241209,749235,746860,748318,748016,748951,747321,748684,
748225,565375,748673,747869,748522,748335,744775,672229,578056,713127,740234,632608,711135,
746528,362131,742223,746567,745224,332989,439837,745418,673582,269584,742606,745135,746950,
476134,740830,742949,276934
I have a MySQL table users with the id field.
How do I check - using a query - which IDs of the ones I have do not exists in the users table?
This sounds like a simple problem to me, yet I couldn't find any example on StackOverflow which would address a fixed set of ID values.
I didn't know the find_in_set() function and took a more handcrafted approach. Not that it makes any sense given the first answer, but I'll post it anyway:
SELECT id
FROM (
SELECT '757392' AS id UNION
SELECT '733602' UNION
SELECT '749955' UNION
SELECT '744304' UNION
SELECT '746852' UNION
SELECT '753904' UNION
SELECT '755117' UNION
SELECT '636163' UNION
SELECT '564931' UNION
SELECT '740787' UNION
SELECT '751450' UNION
SELECT '743799' UNION
SELECT '643918' UNION
SELECT '749903' UNION
SELECT '571888' UNION
SELECT '30207' UNION
SELECT '705953' UNION
SELECT '749120' UNION
SELECT '749001' UNION
SELECT '749192' UNION
SELECT '749978' UNION
SELECT '750840' UNION
SELECT '544228' UNION
SELECT '702121' UNION
SELECT '746246' UNION
SELECT '383667' UNION
SELECT '558790' UNION
SELECT '585628' UNION
SELECT '592771' UNION
SELECT '745818' UNION
SELECT '749375' UNION
SELECT '241209' UNION
SELECT '749235' UNION
SELECT '746860' UNION
SELECT '748318' UNION
SELECT '748016' UNION
SELECT '748951' UNION
SELECT '747321' UNION
SELECT '748684' UNION
SELECT '748225' UNION
SELECT '565375' UNION
SELECT '748673' UNION
SELECT '747869' UNION
SELECT '748522' UNION
SELECT '748335' UNION
SELECT '744775' UNION
SELECT '672229' UNION
SELECT '578056' UNION
SELECT '713127' UNION
SELECT '740234' UNION
SELECT '632608' UNION
SELECT '711135' UNION
SELECT '746528' UNION
SELECT '362131' UNION
SELECT '742223' UNION
SELECT '746567' UNION
SELECT '745224' UNION
SELECT '332989' UNION
SELECT '439837' UNION
SELECT '745418' UNION
SELECT '673582' UNION
SELECT '269584' UNION
SELECT '742606' UNION
SELECT '745135' UNION
SELECT '746950' UNION
SELECT '476134' UNION
SELECT '740830' UNION
SELECT '742949' UNION
SELECT '276934') AS id_list
WHERE id NOT IN (
SELECT id
FROM users);
This is an option:
SELECT ids.id
FROM ( SELECT #i
, substring(#string, #start, #end-#start) id
FROM <BigTable>
, ( SELECT #string := <YourStringOfIds>
, #start:=0
, #end:=0
, #i:=0
, #len:=length(#string)
, #n:=#len-length(replace(#string,',',''))+1
) t
WHERE (#i := #i+1) <= #n
AND (#start := #end+1)
AND (#loc := locate(',',#string,#start))
AND #end := if(#loc!=0,#loc,#len+1)
) ids
LEFT JOIN <BigTable> u
ON u.id = ids.id
WHERE u.id is null
BigTable can be any table whose number of rows >= number of ids in your string.
Create temporary table, then fill it
CREATE TABLE tmp (
`id` INT NOT NULL,
PRIMARY KEY (`id`));
INSERT INTO tmp (id) VALUES (1),(2),(3),(4),(5),(6)
then make a query
SELECT tmp.id
FROM tmp
LEFT JOIN users u ON u.id = tmp.id
WHERE tmp.id IS NULL
finally drop the table
DROP TABLE tmp
You're looking for the IN clause with a negation. I.e. you can specify your list as the argument to the IN clause like so:
SELECT * FROM users
WHERE id NOT IN ( 757392,733602,749955,744304,746852,753904,755117,636163,564931,740787,751450,743799,643918,749903,571888,30207,705953,749120,749001,749192,749978,750840,544228,702121,746246,383667,558790,585628,592771,745818,749375,241209,749235,746860,748318,748016,748951,747321,748684,748225,565375,748673,747869,748522,748335,744775,672229,578056,713127,740234,632608,711135,746528,362131,742223,746567,745224,332989,439837,745418,673582,269584,742606,745135,746950,476134,740830,742949,276934 );
UPDATE
My bad - I didn't read the question properly.
So the correct way would be to go with UNIONs then outer join and filter by NULL, like this:
SELECT WantedIds.id
FROM users
RIGHT JOIN (
SELECT x.id
FROM (
SELECT '757392' AS id UNION
SELECT '733602' UNION
SELECT '749955' UNION
SELECT '744304' UNION
SELECT '746852' UNION
SELECT '753904' UNION
SELECT '755117' UNION
SELECT '636163' UNION
SELECT '564931' UNION
.
.
.
) x
) WantedIds
ON WantedIds.id = users.id
WHERE users.id IS NULL
You can use MySQL's find_in_set() function to check if a value exists in a commase separated list of values:
select * from your_table
where find_in_set(field_name,'757392,733602,749955,744304,746852,753904,755117,636163,564931,740787,751450')=0
How can I select the distinct values and relative count from data that is stored as comma separated values in MySql?
This is how the data in the table looks like:
"Category" "Values"
"red" "D,A,D,D"
"yellow" "A,A,D,D"
Desire Output:
"red" "D" "3"
"red" "A" "1"
"yellow" "D" "2"
"yellow" "A" "2"
Can you think of a good way in mysql to get output like the way I've done?
Thank's in advance.
Using a derived table you can split the string into rows
SELECT `Category`, SUBSTRING_INDEX(SUBSTRING_INDEX(t.`Values`, ',', n.n), ',', -1) `value`
FROM table1 t CROSS JOIN
(
SELECT a.N + b.N * 10 + 1 n
FROM
(SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) a
,(SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) b
ORDER BY n
) n
WHERE n.n <= 1 + (LENGTH(t.`Values`) - LENGTH(REPLACE(t.`Values`, ',', '')))
Then just GROUP BY and COUNT
DEMO
SELECT `Category`, `value`, COUNT(*) as cnt
FROM (
<previous query>
) T
GROUP BY `Category`, `value`