MySQL count() függvény használata limit záradékkal

Bele is vágnék. Ki gondolta volna, hogy egyszer meg akarom számolni majd hány sort kérdeztem le adatbázisból, amikor használtam a limit záradékot, és én magam mondtam meg, hogy maximum hány sor lehet. Most mégis eljött ez a nap. Nézzük a következő lekérdezést:

select count(*) from tablaneve limit 40, 10

Logikusnak tűnne, hogy amennyiben van legalább 50 rekordom a tablaneve táblában, akkor visszaadja a 10-et a count(*) hatására, és ha nincs, akkor pedig annyit, amennyit le tudott kérdezni. De ez nincs így. Nem fog visszaadni egyetlen sort sem. Még csak nullát sem ad eredményül.

Mit lehet tehát tenni?

Létezik mysql-ben a found_rows() nevű furcsa függvény, amit meghívva megkapjuk az előző lekérdezésre illeszkedő sorok száma + a limitben megadott offset értéket. Tehát:

select * from tablaneve limit 40, 10;
select found_rows();

Megkapjuk, hogy 50, amennyiben volt legalább 50 sor. Ha csak 45 sor van az adatbázisban, akkor 45-öt eredményez. Az SQL_CALC_FOUND_ROWS opciót használva az első lekérdezésben azt lehet megmondani a mysql-nek, hogy az utána futtatandó found_rows() függvény hagyja figyelmen kívül a limit-et, és az összes sor számát adja vissza. Tehát:

select SQL_CALC_FOUND_ROWS * from tablaneve limit 40, 10;
select found_rows();

Kimenete lehet akár 300 is, ha a tablaneve táblában 300 rekord van.
Ezek ismeretében tehát a sorok számát meghatározhatjuk, ha az SQL_CALC_FOUND_ROWS használata nélkül lekérdezzük a rekordokat, majd a found_rows() visszatérési értékéből kivonjuk az offset értéket:

select * from tablaneve limit 40, 10;
select found_rows()-40;

Persze így lehet negatív szám is az eredmény. De ha ez probléma, akkor azon is segít egy if.

select * from teszt limit 40, 10;
select if(found_rows() < 40, 0, found_rows()-40);

A másik megoldás két egymásba ágyazott select, ahol a belső select eredménye tölti be a külső select-ben a tábla szerepét, és akkor már használható a count(*) is:

select count(*) from (select * from tablaneve limit 40, 10) as t

Aliast kötelező adni a belső select -nek.
Persze ha nem SQL-ben lett volna szükség erre a számolásra, akkor például PHP-ből meghívtam volna a lekérdezésre a mysql_num_rows() függvényt, és kész vagyok. De a leírtak arra adnak megoldást, amikor már sql-ben szükség van az értékre.

Kategóriák: 
Megosztás/Mentés