mysql limit minimum not being set - php

well this should be easy for someone---
I am trying to select specific rows in a database
SELECT * FROM customers LIMIT 10,20
but it always returns 20 rows
what is going on, and why does the minimum not have any value?

LIMIT X, Y
means that you get Y results starting from number X+1.
So if you want values from 11 to 20 you need to use:
LIMIT 10, 10

You would want to do limit 10 or lmit 0, 10 for 10 results

The second number of the LIMIT clause is the number of rows to be returned, not the last index. if you only want 10 rows, replace 20 by 10 in your query limit clause.
SELECT *
FROM customers
LIMIT 10, 10

Limit with two arguments (x,y) means you get rows from x+1 to y. From the MySQL Manual:
The LIMIT clause can be used to constrain the number of rows returned
by the SELECT statement. LIMIT takes one or two numeric arguments,
which must both be nonnegative integer constants (except when using
prepared statements).
With two arguments, the first argument specifies the offset of the
first row to return, and the second specifies the maximum number of
rows to return. The offset of the initial row is 0 (not 1):
SELECT * FROM tbl LIMIT 5,10;
Retrieve rows 6-15 To retrieve all
rows from a certain offset up to the end of the result set, you can
use some large number for the second parameter.
This statement
retrieves all rows from the 96th row to the last:
SELECT * FROM tbl LIMIT 95,18446744073709551615;
With one argument,
the value specifies the number of rows to return from the beginning of
the result set:
SELECT * FROM tbl LIMIT 5;
Retrieve first 5 rows In other words,
LIMIT row_count is equivalent to LIMIT 0, row_count.

Related

Selecting the next set of records from a MYSQL database table - PHP

I would like to know the syntax of how to construct a sql query that retrieves sets of data from the database. For example, I am able to retrieve a set of 10 records from a table , but then would like to retrieve the next ten after that based on the same query.
PHP
$limit = 10;
$SQl = "SELECT * FROM myTable LIMIT {$limit}";
What would the sql query be for the next 10 records, given that I already have the previous 10 records and would not want them to also be retrieved?
There are two options:
LIMIT 11, 10
and one more:
LIMIT 10 OFFSET 11
Legend:
11 - start row
10 - how much rows

How can I write an SQL query offset by x rows

I'm trying to figure out the fastest way to get x rows from a table that are offset by x rows and ordered by a date column.
The problem I have is I'm paginating the rows from the query into pages of 10 rows per page, but I only need the nth page.
For example if I only need page 4 from the table, I need to select all the rows:
SELECT * FROM posts ORDER BY date
Then I need to paginate the array using PHP and get the 4th page (if it exists). This is less than ideal as it seems a waste to have to get the whole table.
Is there a better way to query the table in this situation?. For example if I have 10 posts per page and I want the the 4th page, is there a way to offset the query so it starts from the 30th row? (and ordered by date).
You're looking for LIMIT
SELECT * FROM posts ORDER BY date LIMIT 10, 20
Where 10 is offset and 20 is the number of rows
LIMIT is the answer. According to MySQL documentation,
The LIMIT clause can be used to constrain the number of rows returned
by the SELECT statement. LIMIT takes one or two numeric arguments,
which must both be nonnegative integer constants (except when using
prepared statements).
With two arguments, the first argument specifies the offset of the
first row to return, and the second specifies the maximum number of
rows to return. The offset of the initial row is 0 (not 1):
SELECT * FROM tbl LIMIT 5,10; # Retrieve rows 6-15

(PHP) MySQL random rows big table with order by and certain range

I have this table:
person_id int(10) pk
fid bigint(20) unique
points int(6) index
birthday date index
4 FK columns int(6)
ENGINE = MyISAM
Important info: the table contains over 8 million rows and is fast growing (1.5M a day at the moment)
What I want: to select 4 random rows in a certain range when I order the table on points
How I do it now: In PHP I randomize a certain range, let's say this gives me 20% as low range and 30% as high range. Next I count(*) the number of rows in table. After I determine the lowest row number: table count / 100 * low range. Same for high range. After I calculate a random row by using rand(lowest_row, highest_row), which gives me a row number within the range. And at last I select the random row by doing:
SELECT * FROM `persons` WHERE points > 0 ORDER BY points desc LIMIT $random_offset, 1;
The points > 0 is in the query since I only want randoms with at least 1 point.
Above query takes about 1.5 seconds to run, but since I need 4 rows it takes over 6 seconds, which is too slow for me. I figured the order by points takes the most time, so I was thinking about making a VIEW of the table, but I have really no experience with views, so what do you think? Is a view a good option or are there better solutions?
ADDED:
I forgot to say that it is important that all rows has the same chance of being selected.
Thanks, I appreciate all the help! :)
Kevin
Your query is so slow, and will become exponentially slower, because using LIMIT here forces it to do a full table sort, and then a full table scan, to get the result. Instead you should do this on the PHP end of things as well (this kind of 'abuse' of LIMIT is actually the reason it's non-standard SQL and for example MSSQL and Oracle do not support it).
First ensure there's an index on points. This will make select max(points), min(points) from persons a query that'll return instantly. Next you can determine from those 2 results the points range, and use rand() to determine 4 points in the requested range. Then repeat for each result:
SELECT * FROM persons WHERE points < $myValue ORDER BY points DESC LIMIT 1
Since it only has to retrieve one row, and can determine which one via the index, this'll be in the milliseconds execution time as well.
Views aren't going to do anything to help your performance here. My suggestion would be to simply run:
SELECT * FROM `persons` WHERE points BETWEEN ? AND ?
Make sure you have an index on points. Also, you SHOULD replace * with only the fields you are concerned about if applicable. Here is course ? represents the upper and lower bounds for your search.
You can then determine the number of rows returned in the result set using mysqli_num_rows() (or similar based on your DB library of choice).
You now have the total number of rows that meet your criteria. You can easily then calculate 4 random numbers within the range of results and use mysqli_data_seek() or similar to go directly to the record at the random offset and get the values you want from it.
Putting it all together:
$result = mysqli_query($db_conn, $sql); // here $sql is your SQL query
$num_records = 4; // your number of records to return
$num_rows = mysqli_num_rows($result);
$rows = array();
while ($i = 0; $i < $num_records; $i++) {
$random_offset = rand(0, $num_rows - 1);
mysqli_data_seek($result, $random_offset);
$rows[] = mysqli_fetch_object($result);
}
mysqli_free_result($result);

getting the i-th to j-th rows within an ordered Mysql query

so suppose I have this query:
SELECT * FROM t WHERE j = k ORDER BY l
is there a way to have the query only return, for example the 20th to 40th records according to the ORDER BY statement rather than returning all the rows ordered by the ORDER BY statement?
SELECT * FROM t WHERE j = k ORDER BY l LIMIT 20, 20
Limit by 20 (the second one), starting from offset 20, the first.
Did you search in the documentation at all?
The LIMIT clause can be used to constrain the number of rows returned
by the SELECT statement. LIMIT takes one or two numeric arguments,
which must both be nonnegative integer constants (except when using
prepared statements).
With two arguments, the first argument specifies the offset of the
first row to return, and the second specifies the maximum number of
rows to return. The offset of the initial row is 0 (not 1).
SELECT * FROM tbl LIMIT 5,10; # Retrieve rows 6-15
For compatibility with PostgreSQL, MySQL also supports the LIMIT row_count OFFSET offset syntax.
LIMIT + OFFSET
SELECT * FROM t WHERE j = k ORDER BY l LIMIT 19,21
Note:
the offset is zero based so 19 = start at row 20
and there are 21 rows between 20 and 40 inclusive
SELECT * FROM t WHERE j = k ORDER BY l LIMIT 20 OFFSET 20;
limit says you only need 20 rows, and offset says you don't need the first 20 rows.
Keep in mind that when the offset value is very large, your query will be very slow, since the sql server will need to scan the first <offset> rows to return <offset>+<limit> rows to you.
http://dev.mysql.com/doc/refman/5.0/en/select.html
sample: SELECT * FROM tbl LIMIT 5,10; # Retrieve rows 6-15
so
SELECT * FROM t WHERE j = k ORDER BY l LIMIT 20,20; #retrieve rows 20-40
There's solution:
SELECT * FROM t WHERE j = k ORDER BY l limit 21, 20; (21 is number of rows and 20 is starting row, so you will retrieve rows from 20th to 40th if they exists)

PHP output couple times data from a column

How do I output data from column, but to be like.. for example - the column is with 40 lines of query results and I want to output only that, that are from 10 to 30 . How to do it with PHP?
For MySQL, you could use a LIMIT offset, maxrows:
SELECT * FROM tbl LIMIT 9,20;
will get you rows 10-30. Note that the offset value is 0 based, hence the 9 rather than 10.

Categories