FOUND_ROWS() in MariaDB 10 - mysql

I have a function which needs the number of rows returned by a select. After some googling i found the FOUND_ROWS() function. But i don't think it works:
SELECT * FROM tipfirme LIMIT 20;
SELECT FOUND_ROWS();
because it always returns 1 as the found value.
However, if i run it in one line, it works.
SELECT FOUND_ROWS() FROM (SELECT * FROM tipfirme LIMIT 20) as T
Am i doing something wrong or is the function broken?

FOUND_ROWS returns the number of rows the previous request (entire select statement) returned. It sounds to me like you are wanting just:
select count(1) from (select * From tipfirme limit 20) as T
select found_rows(); separately would not always return 1; I suspect you were not testing what you meant to test. If it immediately follows select * from tipfirme limit 20; it would indeed return the number of rows the select returned (after the limit, or before the limit if you specified sql_calc_found_rows in the previous select).
SELECT FOUND_ROWS() FROM (SELECT * FROM tipfirme LIMIT 20) as T isn't doing what you think; it will return as many rows as the subselect returned, and each will have the number of rows the previously executed select returned, not related to the number of rows from the subselect at all.

Related

Returning a range of rows in MySQL relative to either beginning or end of the result set

I've got a query that is returning a set of rows. I want to LIMIT what actually gets returned to some subset of these rows by range, relative either to the beginning or end of the range. I can do this easily if the range is only relative to the beginning. For instance, if I want to return rows 5-7 I can do:
SELECT * FROM <table> WHERE <condition> ORDER BY rowid ASC LIMIT 5,2
The only translation I need to do is from (index0,index1) to offset,length where offset=index0 and length=index1-index0.
But I also am trying to allow the range to be specified relative to the end of the range in a single query, i.e. without running a query first to determine the number of rows and then a second query based on this information. So for example if I specify a row range of (-5,-1) this means that I want the last five rows returned. I cannot pass a negative value to LIMIT.
In reading similar questions, one proposed solution seemed to be to change the ORDER of the query. So I suppose I could do:
SELECT * FROM <table> WHERE <condition> ORDER BY rowid DESC LIMIT 1,5
Now I have two problems. First, the returned set is in the wrong order, I still want it return in ascending order. So now I have to have a subquery to reorder everything:
SELECT * FROM (SELECT * FROM <table> WHERE <condition> ORDER BY rowid DESC LIMIT 1,5) AS x ORDER BY x.rowid ASC;
I'm not sure if there is a better way to do it than that, but there is a second issue: this does not work if the starting and ending part of the range are mixed as to what they are relative to. Suppose I want to return the range (10,-2) which is all rows from the tenth to the next to last. In this case, neither of the above approaches will work.
I also saw where the function mysql_num_rows() was mentioned although it did not give example SQL of how to use it.
SELECT * FROM <table> WHERE <condition> ORDER BY rowid DESC LIMIT 10,mysql_num_rows()-2;
But when I try to run this query, I get this error:
ERROR 1327 (42000): Undeclared variable: mysql_num_rows
What about reversing your approach? Asking for rows in range (10, -2) means "everything except first nine rows and last one".
You can translate it into
select * from yourTable order by rowid asc
minus
select * fom yourTable order by rowid asc limit 9
minus
select * fom yourTable order by rowid desc limit 1
Edit
Since MySQL does not support MINUS, the query above could be rewritten using left join instead
select t1.*
from yourTable t1
left join
(select rowid fom yourTable order by rowid asc limit 9) t2
on t1.rowid = t2.rowid
left join
(select rowid fom yourTable order by rowid desc limit 1) t3
on t1.rowid = t3.id
where t2.rowid is null and t3.rowid is null
order by t1.rowid asc
This is based on a different answer that was given to this question, which used MINUS. Unfortunately, MySQL does not support this operator. I used NOT IN instead, and furthermore I had to wrap my query inside additional queries to avoid the MySQL issue of lack of support for LIMIT being in an IN sub-query.
So the premise of the solution as provided by the other answer is to treat a positive starting index and a negative ending indexes as a different case from both indicies negative or positive. Then, select everything but exclude the range at the start and finish. The actual code that MySQL likes and which works for the example range of (10,-2) is:
SELECT *
FROM <table>
WHERE <conditions>
AND rowid NOT IN
(
SELECT * FROM (
SELECT rowid FROM <table> WHERE <conditions> ORDER BY rowid ASC LIMIT 9
)
)
AND rowid NOT IN
(
SELECT * FROM (
SELECT rowid FROM <table> WHERE <conditions> ORDER BY rowid DESC LIMIT 1
)
)
Or more generally, for the range (i0,i1) where i0>=0 and i1<0, replace 9 with i0-1 and 1 with -i1-1. Of course, if either of these values are less than one, that portion of the query can be excluded.

select all the rows from my table except the first 20 rows

I want to select all the rows from my table except the first 20 rows. How it possible? The total number of rows are not static.
SELECT statistics_id,title, user_name FROM (
SELECT statistics_id,title, user_name FROM statistics ORDER BY statistics_id DESC
LIMIT(select count(*)from statistics )-20
) sub
ORDER BY access_statistics_id ASC
I know 'LIMIT(select count(*)from statistics )-20' is not a correct method. Please help.
the documentation says (https://dev.mysql.com/doc/refman/5.5/en/select.html) the following:
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;
so you could use something like
LIMIT 20, veryLargeNumber
Try this
DECLARE v_max bigint unsigned default ~0;
SELECT statistics_id,title, user_name
FROM statistics
LIMIT 20, v_max;
After writing the select query u just have to include,
LIMIT 21,100;
21-Offset i.e from which row you want to start selecting and
100- is the Limit[Which you can set according to your need]
You actually need:
SELECT
statistics_id, title, user_name
FROM statistics
ORDER BY
statistics_id ASC
LIMIT 20, 18446744073709551615;
As per MySQL Documentation
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;
If your table grows fast, selecting all rows (with exception of first 20) is not a good idea. In such case, you should batch your query, and handle a subset of entries at a time, some thing like:
SELECT * FROM tbl LIMIT 20,120;
Try using the offset option for the LIMIT syntax. you can read more about the LIMIT syntax at http://dev.mysql.com/doc/refman/5.0/en/select.html.
SELECT `statistics_id`
, `title`
, `user_name`
FROM `statistics`
ORDER BY `statistics_id` ASC
LIMIT 20, 18446744073709551615

MySQL FOUND_ROWS & total rows

I'm doing the following
n = 10
SELECT SQL_CALC_FOUND_ROWS * FROM tbl_name
WHERE id > 100 LIMIT n, 20;
SELECT FOUND_ROWS();
However, n is set by the user. Is there a way to know that n won't go over the total # of rows without having to run the query twice?
I don't see how you could possibly accomplish your goal without running two queries.
You can run a different query to count the number of results that would be returned, and then check that number against the users value.
Very little SQL knowledge in general here, but I'll attempt to help.
What happens if it is over the boundary? Do you just select the last 20? I'm not sure. From what it looks like on the MySQL reference, the LIMIT x, y means results start at the xth value returned and returns y records (x and the y-1 records following). So it would seem you need to check and make sure that n isn't greater than your count - 20.
DECLARE #blah INT;
IF (n <= (SELECT Count(*) FROM tbl_name) - 20) THEN SET #blah = n;
ELSE SET #blah = (SELECT Count(*) FROM tbl_name) - 20;
SELECT SQL_CALC_FOUND_ROWS * FROM tbl_name WHERE id > 100 LIMIT #blah, 20;
SELECT FOUND_ROWS();
END IF

How do I select count() and LIMIT?

SELECT * FROM ...LIMIT 5, 10
But what if I want the total rows? I don't want to make another query without the limit. I just want this one query to return the total rows if I didn't put the LIMIT in there.
the only way is like this (use 2 queries):
SELECT SQL_CALC_FOUND_ROWS ..... FROM table WHERE ... LIMIT 5, 10;
and right after run this :
SELECT FOUND_ROWS();
read more :
http://www.arraystudio.com/as-workshop/mysql-get-total-number-of-rows-when-using-limit.html
http://dev.mysql.com/doc/refman/5.0/en/information-functions.html#function_found-rows
Use
select count (*) from table_name

Omit the first 5 rows?

I want to SELECT all rows except for the first 5 rows in a table.
How do I do that?
Why can't I just type
$query = "SELECT *
FROM ages
OFFSET 5
ORDER BY id ASC";
SELECT * FROM tbl LIMIT 5,18446744073709551615;
from http://dev.mysql.com/doc/refman/5.0/en/select.html
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;
In Oracle:
select name, price
from items
where rownum > 5
Here's a solution using variables - just add your order by clause and you should be set.
set #n=-1
select * from TABLE where (#n:=#n+1) >= 5;
I just typed:
$query = "SELECT *
FROM ages
LIMIT 100
OFFSET 10";
Why couldn't anybody give me such an easy answer? :)