MySQL query to assign a unique random number to each row - mysql

I wish to attach a column to my table which will be a random number from a sequential list = to the number of rows.
So, if my table had 999 rows, then the numbers 1 to 999 would be assigned randomly and uniquely.
Now, I figured that I could add a dummy TempRandomColumn=Rand(), sort by that and add the numbers sequentially using PHP. But that means 999 MySQL statements.
Is there a way to do this using a single MySQL statement?
Thanks for any pointers.

SET #r := 0;
UPDATE items2
SET author_id = (#r := #r + 1)
ORDER BY
RAND()

SET #i=1;
SELECT t.*, #i:=#i+1 as RAND_NUM FROM your_table t ORDER BY RAND();

Related

How to easily get row number when using LIMIT in MySQL?

Suppose I have a database table with quite a few rows which I want to display to an user. It would make sense to LIMIT the output, and make pages of rows. In MySQL I would do this:
SELECT * FROM myTable ORDER BY myValue LIMIT 120,10
which will show 10 rows starting from row 120. So MySQL must use, internally, some kind of order, and has numbered the rows accordingly. I would like to display the row number with each row. How do I get access to these numbers, using only MySQL? To be clear, I am looking for something like this:
SELECT *,<LIMIT_ROWNO> FROM myTable ORDER BY myValue LIMIT 120,10
I looked online and in the manual, but I cannot find it. I would prefer something simple, without using variables, or functions. Isn't there a predefined expression for this?
I can solve this problem easily in PHP, but it would be more logical to get the row numbers from MySQL.
You can't do it without using variables, e.g.:
SELECT m.*, #rownum := #rownum + 1 as `num`
FROM myTable m, (SELECT #rownum := 120) a
ORDER BY myValue LIMIT 120,10;
set #rownum=120;
SELECT *,#rownum:=#rownum+1 as rn FROM myTable ORDER BY myValue LIMIT 120,10;
as of final of 2021, why not:
SELECT
t1.*,
COUNT(t1.*) OVER (PARTITION BY RowCounter) as TotalRecords
FROM (
SELECT a, b, c, 1 as RowCounter
FROM MyTable
) t1
LIMIT 120,10
using a subquery with a column marking every row with the same value, will give us the possibility to count all of the same values of the the resulted column with PARTITION BY window function's group

How to select some rows from MySQL table using theirs numbers?

I have a set of rows (it is actually filtered and ordered mysql table).
I also have a set of integer numbers like (5,9,12,67,2,3) which I want to use as row numbers.
Question: What is better way to fetch rows from this set using these numbers?
Example: I have a set 15 rows. And numbers (1,5,7). How I can get 1st,5th and 7th rows?
Try to use this code
select * from (SELECT *, #rowid:=#rowid+1 as rowid FROM table, (SELECT #rowid:=0) as init WHERE ... order by ...) t where t.rowid in (...set of numbers...)
Sorry I just singed up and don't know the good habit to answer so I'll try this:
If You have auto_increment index use that?
If not you can make arbitrary number like
SELECT #currentRow := #currentRow + 1 AS row_number, *
FROM table, (SELECT #currentRow:=0) as init
WHERE row_number IN 1,5,7
(something is wrong with WHERE)
Yes i got it figured out but #Epsiloncool seemd to do it much faster.
Triple select helps you to get where:
SELECT * FROM
(SELECT *, #currentRow := #currentRow + 1 AS row_number
FROM table t, (SELECT #currentRow := 0) AS init) AS table
WHERE cdees.row_number IN 1,5,7

How to select rows between two index

we can select row from index i to j with below code in Sql server.how to do it in mysql?
select * from
(SELECT ROW_NUMBER() OVER (ORDER BY FieldName asc) as row,
* from TableName)
WHERE row between STARTINDEX AND ENDINDEX
I'm not sure did I understand question totally correct, because I'm not super-familiar with SQL: You want to order results by FieldName and select some portion of results based on row numbers you created. I would write that in MySQL like this:
SELECT *
FROM TableName
ORDER BY FieldName ASC
LIMIT STARTINDEX-1, ENDINDEX-STARTINDEX
In MySQL LIMIT index starts from zero (in your SQL-code from 1) and other number in LIMIT clause is number of records you are willing to get
EDIT: My result was missing row number. In case you want row number in your result, it would go like this:
SET #num = STARTINDEX-1;
SELECT #NUM := (#NUM + 1) AS row, TableName.*
FROM TableName
ORDER BY FieldName ASC
LIMIT STARTINDEX-1, ENDINDEX-STARTINDEX
STARTINDEX is same as first row's number because SELECT will add one to #NUM even at the first time

Inserting random numbers into a table in MYSQL

Im trying to count the number of rows in the table and generate random numbers for the field 'random'
Now this works:
SELECT COUNT(*) FROM my_table;
and this works:
UPDATE my_table SET random = FLOOR(6500 * RAND()) + 1;
But this doesn't work:
UPDATE my_table SET random = FLOOR((SELECT COUNT(*) ) * RAND()) + 1;
But this counts the rows as 0 and adds one so all fields have the number one instead of a unique random number.
Any ideas what I'm doing wrong would be most helpful.
What about this?
SELECT #cnt := count(*) FROM my_table;
UPDATE my_table SET random = FLOOR(#cnt * RAND()) + 1;
Demo: http://sqlfiddle.com/#!2/a896d/4
You're asking what are you doing wrong. As the MySQL manual says "Currently, you cannot update a table and select from the same table in a subquery." What this means is that you can't do something like
update my_table set random = (select min(my_field) from r);
where you are doing a complete select as part of the update.
However, you can use a select without an error as you found, but the results are not what you expect - the scope of the SELECT statement as you used it is just the row being worked on at the time. You can test this by creating a field called num and doing this:
update my_table set random = (select count(*));
You'll see that random is set to 1 for every row, since the select is looking at just the one row you are updating at that moment.
The solution is to calculate the number of rows, store it in a variable, and reference that variable in another statement.
SET #row_count = count(*) from my_table;
UPDATE my_table SET random = FLOOR(#cnt * RAND()) + 1;

How do you select every n-th row from mysql

I have a series of values in a database that I need to pull to create a line chart. Because i dont require high resolution I would like to resample the data by selecting every 5th row from the database.
SELECT *
FROM (
SELECT
#row := #row +1 AS rownum, [column name]
FROM (
SELECT #row :=0) r, [table name]
) ranked
WHERE rownum % [n] = 1
You could try mod 5 to get rows where the ID is multiple of 5. (Assuming you have some sort of ID column that's sequential.)
select * from table where table.id mod 5 = 0;
Since you said you're using MySQL, you can use user variables to create a continuous row numbering. You do have to put that in a derived table (subquery) though.
SET #x := 0;
SELECT *
FROM (SELECT (#x:=#x+1) AS x, mt.* FROM mytable mt ORDER BY RAND()) t
WHERE x MOD 5 = 0;
I added ORDER BY RAND() to get a pseudorandom sampling, instead of allowing every fifth row of the unordered table to be in the sample every time.
An anonymous user tried to edit this to change x MOD 5 = 0 to x MOD 5 = 1. I have changed it back to my original.
For the record, one can use any value between 0 and 4 in that condition, and there's no reason to prefer one value over another.
SET #a = 0;
SELECT * FROM t where (#a := #a + 1) % 2 = 0;
I had been looking for something like this. The answer of Taylor and Bill led me to improve upon their ideas.
table data1 has fields read_date, value
we want to select every 2d record from a query limited by a read_date range
the name of the derived table is arbitrary and here is called DT
query:
SET #row := 0;
SELECT * FROM ( SELECT #row := #row +1 AS rownum, read_date, value FROM data1
WHERE read_date>= 1279771200 AND read_date <= 1281844740 ) as DT WHERE MOD(rownum,2)=0
If you're using MariaDB 10.2, MySQL 8 or later, you can do this more efficiency, and I think more clearly, using common table expressions and window functions.
WITH ordering AS (
SELECT ROW_NUMBER() OVER (ORDER BY name) AS n, example.*
FROM example ORDER BY name
)
SELECT * FROM ordering WHERE MOD(n, 5) = 0;
Conceptually, this creates a temporary table with the contents of the example table ordered by the name field, adds an additional field called n which is the row number, and then fetches only those rows with numbers which are exactly divisible by 5, i.e. every 5th row. In practice, the database engine is often able to optimise this better than that. But even if it doesn't optimise it any further, I think it's clearer than using user variables iteratively as you had to in earlier versions of MySQL.
You can use this query,
set #n=2; <!-- nth row -->
select * from (SELECT t.*,
#rowid := #rowid + 1 AS ID
FROM TABLE t,
(SELECT #rowid := 0) dummy) A where A.ID mod #n = 0;
or you can replace n with your nth value
SELECT *
FROM (
SELECT #row := #row +1 AS rownum, posts.*
FROM (
SELECT #row :=0) r, posts
) ranked
WHERE rownum %3 = 1
where posts is my table.
If you don't require the row number in the result set you can simplify the query.
SELECT
[column name]
FROM
(SELECT #row:=0) temp,
[table name]
WHERE (#row:=#row + 1) % [n] = 1
Replace the following placeholders:
Replace [column name] with a list of columns you need to fetch.
Replace [table name] with the name of your table.
Replace [n] with a number. e.g. if you need every 5th row, replace it with 5