/ Forside / Teknologi / Udvikling / SQL / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
SQL
#NavnPoint
pmbruun 1704
niller 962
fehaar 730
Interkril.. 701
ellebye 510
pawel 510
rpje 405
pete 350
gibson 320
10  smorch 260
mysql, limit, sql_calc_found_rows
Fra : Leif Neland


Dato : 09-09-08 16:12

Mysql, version 5.0.45-Debian_1-log

Jeg prøver at benytte sql_calc_found_rows:

Jeg har set tricket med at lave det som en union, for at omgå en bug med
at det ikke nødvendigvis er den query, jeg er intresseret i, men den
query, der tilfældigvis kan være kørt af en anden "instance" af websiden
(eller en anden), når webserveren er belastet.
http://dk2.php.net/manual/en/function.mysql-num-rows.php#76463

(WHERE 1=1 AND ... bliver optimeret væk; det er for lettere at kunne
bygge queryet dynamisk)

SELECT SQL_CALC_FOUND_ROWS '0' dummy, `id` FROM `Blog`
WHERE 1 =1
AND `entry` LIKE ('%Mandag%')
UNION (SELECT '1' dummy, FOUND_ROWS()
)
order by dummy desc, id desc


Det giver fint antallet af records = 36
dummy    id
1    36
0    3266
0    2972
0    2652
..........................................................

Men ideen er jo at "page" igennem et recordsæt:

SELECT SQL_CALC_FOUND_ROWS '0' dummy, `id` FROM `Blog`
WHERE 1 =1
AND `entry` LIKE ('%Mandag%')
UNION (SELECT '1' dummy, FOUND_ROWS()
)
order by dummy desc, id desc
LIMIT 3,6

Men så får jeg ikke den første række, der giver antallet af records med.

dummy    id
0    2652
0    2299
0    1875
0    1872
.................................................................

Ok, så sætter jeg limit op i den første query:
SELECT SQL_CALC_FOUND_ROWS '0' dummy, `id` FROM `Blog`
WHERE 1 =1
AND `entry` LIKE ('%Mandag%')
LIMIT 3,6
UNION (SELECT '1' dummy, FOUND_ROWS()
)
order by dummy desc, id desc

dummy    id
1    36
0    258
0    256
0    207

Nu tager den de første rækker i tabellen, ikke sorteret efter id
descending, og sorterer resultatet af union bagefter.
...................................................................
Ok, hvad med en LIMIT i den første del?

SELECT SQL_CALC_FOUND_ROWS '0' dummy, `id` FROM `Blog`
WHERE 1 =1
AND `entry` LIKE ('%Mandag%')
ORDER BY id desc
LIMIT 3,6
UNION (SELECT '1' dummy, FOUND_ROWS()
)
order by dummy desc, id desc

Nej: #1221 - Incorrect usage of UNION and ORDER BY
....................................................................
Ok, parenteser da?
SELECT SQL_CALC_FOUND_ROWS '0' dummy, `id` FROM `Blog`
WHERE 1 =1
AND `entry` LIKE ('%Mandag%')
ORDER BY id desc
LIMIT 3,6
UNION (SELECT '1' dummy, FOUND_ROWS()
)
order by dummy desc, id desc

Joe, nu kommer der da de ønskede rækker, i den rigtige rækkefølge, men
hvor kommer rækkeantallet "9" fra i den første række??

dummy    id
1    9
0    2299
0    1875
0    1872
0    1487
0    1444
0    1415

Det ser ud til, at når jeg sætter "LIMIT 3,6" så er der et query, der
finder record 1-9 frem, og returnerer de 6 records 4,5,6,7,8,9

Så found_rows() returnerer altså start+count af limit start,count.

Det kan jeg jo heller ikke bruge til noget; der er, som vist tidligere,
35 relevante rækker.

Det skal måske ligefrem bugrapporteres til MySql?
........................................................................
Skal jeg virkelig undlade at sætte limit, og i stedet bruge
mysql_data_seek() til at "spole frem" til de records, jeg vil page?

Eller lave to queries, et med "select count(*)" og et andet, der
returnerer data og har LIMIT $start,$count ?

Eller mon det vil gøre forskel hvis jeg laver det som en stored
procedure med først et query på tabellen, og bagefter et query efter
found_rows() ? Men så bliver det vel ikke muligt at lave queryet
dynamisk, som jeg gør nu, med

if ($_GET['author']) {$addsql=sprintf(" AND author='%s'
",mysql_real_escape_string($_GET['author'])) };

Leif

 
 
Søg
Reklame
Statistik
Spørgsmål : 177428
Tips : 31962
Nyheder : 719565
Indlæg : 6407944
Brugere : 218877

Månedens bedste
Årets bedste
Sidste års bedste