Random row from big query result - mysql

I need to get 1-2 rows from query result retrived with SQL select on indexed columns without getting the whole record set.
For example I will retrieve 10 000 records using query
SELECT * FROM table WHERE field 1>1 AND field1 < 10
but I need only 1 random row from this query regarding to highload of my database.
I can use
SELECT * FROM table WHERE field 1>1 AND field1 < 10 LIMIT 100, 1
But I don't know records numebr to use correct offset range
How can I achieve this goal?

You could use ORDER BY RAND()
SELECT * FROM table WHERE field1 > 1 AND field1 < 10 ORDER BY RAND() LIMIT 1
This will return 1 random row with field1 in between 1 and 10

How about restricting the records you select in the first place?
SELECT * FROM table WHERE field1 IN (CONVERT(RAND()*10,SIGNED),CONVERT(RAND()*10,SIGNED)) LIMIT 2

Related

SQL - MYSQL One query recieving set limit on different column values

Lets say i have a table with a set of different columns (offcourse),
Example :
Table
id
col1 INTEGER(1), // 0 || 1
col2 // --||--
col3 // --||--
col4 // --||--
Is it possible, in 1 query to select 4 rows where col1=1 and then select 4 rows where col2=1 and then select 4 rows where col3=1 etc etc. I think you understand what i mean.
What i have done so far is to make 4 different queries OR make one query and just do a (col1 = 1 OR col2=1 OR... etc).
This works but if i limit that result to lets say 16, then i might get 15 rows with col1=1 and maybe 1 row with col2=1 and then col3,col4 - no result.
So dear fellas; is there a way to do this in 1 query (i think not)
Select * from table where col1=1 limit 4
Union
Select * from table where col2=1 limit 4
Union
Select * from table where col3=1 limit 4
Union
Select * from table where col4=1 limit 4
This will get you one result with 16records max. If there are less then 4rows for a certin criteria, you'll get less rows. Duplicates will be removed, resulting in less then 16 rows. Not different rows.
If for a single row col1=1 and col2=1, then it might be returned twice if you use union all, but just union is slower with large datasets
I think you are looking for the UNION ALL construct. You may simply write
SELECT * FROM tab WHERE col1 = 1
UNION ALL
SELECT * FROM tab WHERE col2 = 2
UNION ALL
SELECT * FROM tab WHERE col3 = 3
and so on. Just be aware of a fact that the rows may be duplicated in the result (if they satisfy more criteria from the conditions).

Query Limit from MYSQL

I have database with about 500K row in it. I want get random row from row like 1 to 5000 and its limit result limit need like 100.
My current query is like below
'SELECT * FROM user where status='0' LIMIT 10,100'
what should I change or use for get limited random row, so I can get fast result without memory consume ?
Thanks
A database table is an unordered set, so you'll have to provide some order to get 1 to 5000 rows (otherwise those will be any 1 to 5000 rows), may be based on userid.
Once you have that, you can limit the rows in subquery and sort by rand() and get first 100 like this:
select *
from (select
*
from user
where status = 0
order by /* set of columns, may be user_id*/
limit 1, 5000
) t order by rand() limit 100;
This query gives you any 100 random rows from your 5000k rows
select * from user where status='0' order by rand() limit 100

MySql Select Id <= Maximum value in the table

When using the <= in a MySql statement, is it possible to make MySql select the maximum value in a table without supplying a value to <= in the sql statement?
Eg:
id
----
1
2
3
4
5
6
Eg:
// start from the last record when no value is supplied
select id from table where id <= * ORDER BY id DESC LIMIT 5
Result
6
5
4
3
2
// start from the 5th record when a value is supplied
select id from table where id <= 5 ORDER BY id DESC LIMIT 5
Result
5
4
3
2
1
My problem is, this statement is in a php function, so I cannot change it dynamically. Is it somehow possible to do what I'm trying, or perhaps another way to get around this?
You can use NULL instead of using *
SET #var_search_value = NULL -- OR 5
SELECT id
FROM table
WHERE id <= #var_search_value OR #var_search_value IS NULL
ORDER BY id DESC LIMIT 5
If you want to get every record which is less than or equal to the maximum value in a particular column, then logically you want to get every record:
select id from table ORDER BY id DESC LIMIT 5
No WHERE clause is required.

mysql rows 16-21

If I have a table: ID, num,varchar
where ID is an integer, either 1,2 or 3.
then num is a number, counting from 1 to 100.
varchar is just some text.
So in total we have 300 rows, in no particular ordering in this table.
What query can I use to get the rows with ID=2 and num from 16-21 out of this table?
(resulting in 6 rows total)
How about
SELECT * from yourtable where ID = 2 AND num >= 16 AND num <= 21
Or, equivalent using BETWEEN
SELECT * from yourtable where ID = 2 AND num BETWEEN 16 AND 21
Create an index to have faster lookups later (but will slow down your inserts a bit):
CREATE INDEX indexname on yourtable (ID,num);
SELECT * FROM TABLE WHERE ID = 2 AND NUM > 15 AND NUM < 22;
where TABLE is the name of your table. In general, given that you're selecting on columns ID and NUM they should probably be indexed for faster retrieval (ie the database doesn;t have to check every row). Although given your table is small it probably wont make much difference here.
This should do it:
SELECT * FROM table WHERE id = 2 AND num > 15 AND num < 22

Recordset Iterating

I want to iterate through records returned from a MySQL database using Perl, but only ten records at a time. The reason is that the server component can only handle 10 items per request.
For example:
If the query returned 35 records then
I have to send the data in 4 requests:
Request # # of Records
-------- --------
1 10
2 10
3 10
4 5
What is the best way to accomplish the task?
Look at the LIMIT clause for MySQL. You could have a query like:
SELECT * from some_table LIMIT 0, 10;
SELECT * from some_table LIMIT 10, 10;
etc. where the first number after LIMIT is the offset, and the second number is the number of records.
You'd of course first need to do a query for the total count and figure out how many times you'll need to run your select query to get all results.
Alternatively, in Perl you can use an ORM package like DBIx::Class that can handle pagination through sets of results and auto-retrieving them for you.
You can adjust the query to select 10 rows:
select *
from yourtable
order by idcolumn
limit 10;
When iterating over the rows, store the ID of the row you process. After you've processed 10 rows, fetch the next 10:
select *
from yourtable
where idcolumn > stored_id
order by idcolumn
limit 10;
Continue the last query until it returns less than 10 rows.
For first page:
SELECT *
FROM table1
ORDER BY
field
LIMIT 0, 10
For seconds page:
SELECT *
FROM table1
ORDER BY
field
LIMIT 10, 10
etc.