ugrás a tartalomhoz

MYSQL LIMIT másként

world-s · 2008. Szep. 10. (Sze), 20.51
Sziasztok!

Lenne egy problémám, amit nem igazán tudom, hogyan érdemes megcsinálni úgy, hogy ne egyesével kérdezzem le a rekordokat.

Csinálok egy oldalt, ami mobiltelefonra készült, ahol nagyon kötött ugye, hogy egy oldalra mennyi szöveg mehet. Az oldalon hozzászólások lennének egymás alatt felsorolva.

Az, hogy hány hozzászólás kerüljön egy oldalra, az függ attól, hogy egy hozzászólás milyen hosszú.

Pl. ha a hozzászólások 300 karakter hosszúak, akkor lehet 3 kifér egy oldalra, de ha csak 30 karakter hosszúak, akkor jóval több is. A szépsége ugye hogy a felhasználóktól függően minden hozzászólás eltérő hosszú lesz.

Ebből adódóan nem tudom használni a LIMIT paramétert, mert nem tudom hány rekordra van szükségem.

A fapados megoldás, hogy egyesével olvasgatom a rekordokat külön-külön SELECT-tel, és vizsgálom kell -e még, de szerintem ez eléggé terhelő lehet nagy forgalom esetén.

Milyen megoldást ajánlanátok ti?:
-megtudjam, mennyi hozzászólás fér el egy-egy oldalon (legalábbis mennyit kérjek le az adatbázisból)

-hány oldalra férnek el a hozzászólások összesen (ez nem annyira lényeg, max nem írom ki hány oldal van)

- miként tudom meghatározni, hogy hány rekordot kell beolvasnom ha egy oldalról visszább lépek az előzőre.

Mindenki segítségét előre is köszönöm.


Üdv:
Zoli
 
1

Biztos jo elgondolas?

Protezis · 2008. Szep. 10. (Sze), 21.14
Nem veletlenul lehet a legtobb forumon kivalasztani, hogy hany hozzaszolas legyen egy oldalon. Szerintem zavaro, ha ez dinamikus, az egyes hozzaszolasok hosszatol fugg. Ha nagyon egyseges kinezetet akarsz az oldalakon ( gondolom ez lenne a cel ), inkabb fix meretu reszbe toltsd a szoveget, rakj ra egy overflow: hidden-t, es ha a user vegig akarja olvasni, rabok egy linkre, aminek hatasara megjelenik a teljes szoveg ( mondjuk javascripttel ezt eleg szepen meg lehet oldani ).
2

Köszi a gyors választ

world-s · 2008. Szep. 10. (Sze), 21.26
Köszi a gyors választ!

Amit mondasz az nagyon logikus és én is így csinálnám, de sajnos telefonra készült WAP (WML és XHTML) oldalakról van szó, így kiesett a JavaScript.
Kiesett az is hogy minden hozzászólást egyesével ki kellene fejteni, mert a sok nyomogatás miatt használhatatlan lenne az oldal.
A fix darabszámot azért tartottam rossz megoldásnak, mert ha 50 felhasználó csak egy-egy vigyort nyom, akkor elég idegesítő 2-3 vigyoronként lapozgatni, holott lehet 30 is kiférne egy oldalra.

Üdv:
Zoli
3

??

world-s · 2008. Szep. 10. (Sze), 22.16
Valami ilyesmivel próbálkozok:


SET @b:=0;
SELECT * , @b := @b + LENGTH( `Memo` ) AS `c` 
FROM `comment` 
WHERE @b <600

Ezzel ugye csoportokra tudom szedni a rekordokat.
Kérdés, most hogy tudok pozícionálni előre és hátra.

Feltételezve, hogy ez a jó kiindulási alap.

Zoli
4

Egy lehetséges magoldás

world-s · 2008. Szep. 11. (Cs), 12.52
Sziasztok!

Eljutottam egy lehetséges megoldáshoz, de nem tudom hogy esetleg ennél nincs -e jobb, vagy hatékonyabb, mert itt dupla select van.



SET @szamol :=0;
SELECT * from (SELECT * , LENGTH(`Comment`) AS `a` , 
CASE WHEN (
@szamol + LENGTH( `Comment` ) 
) <40
THEN @szamol := @szamol + LENGTH(`Comment`) 
ELSE @szamol := LENGTH( `Comment` ) 
END b
FROM `comment` ) AS tmp 
WHERE a=b;


Esetleg ha a rekordok feltöltésénél kiszámolom a hozzászólások hosszát és azt külön tárolnám egy mezőben, akkor nem kellene az SQL-nek mindig átolvasnia az összes rekordot.

Vagy más ötlet?

Üdv:
Zoli
5

előre letárolás

Hodicska Gergely · 2008. Szep. 11. (Cs), 14.00
Esetleg ha a rekordok feltöltésénél kiszámolom a hozzászólások hosszát és azt külön tárolnám egy mezőben
Én is erre gondoltam amikor írtad az előző postot, illetve azt szerettem volna átgondolni, hogy nem lehet-e egyből valamilyen aggregált adatot letárolni, ami lapján már adódik a lapozás, csak aztán elakadtam vele: állandó-e a rendezés, lehetnek-e szűrések stb.. De hosszt szerintem mindenféleképpen megéri letenni előre.


Üdv,
Felhő
6

re

world-s · 2008. Szep. 11. (Cs), 16.18
Ez az újjabb algoritmusom:


SET @szamol :=0;
SET @groupom :=0;
SELECT *
FROM (
SELECT * , LENGTH( `Comment` ) AS `a` , 
CASE WHEN (
@szamol + LENGTH( `Comment` ) 
) <40
THEN @groupom 
ELSE @groupom := @groupom +1
END groupom, 
CASE WHEN (
@szamol + LENGTH( `Comment` ) 
) <40
THEN @szamol := @szamol + LENGTH( `Comment` ) 
ELSE @szamol := LENGTH( `Comment` ) 
END b
FROM `comment` 
ORDER BY `Num` DESC 
) AS tmp
WHERE groupom  = 0
Ez már a rekordokat is visszaadja egyből. Csak meg kell adnom a groupom-ba melyik oldalt szeretném.

Üdv:
Zoli
7

???

world-s · 2008. Szep. 11. (Cs), 23.04
Kicsit tovább néztem mikor a darabszám meghatározása miatt szerettem volna egyszerűsíteni a képletemet.


Elméletileg ennek is kellene menni:

SET @szamol :=0;
SET @groupom :=0;

SELECT * ,@groupom , LENGTH( `Comment` ) AS `a` , 
CASE WHEN (
@szamol + LENGTH( `Comment` ) 
) <40
THEN @groupom 
ELSE @groupom := @groupom +1
END groupom2, 
CASE WHEN (
@szamol + LENGTH( `Comment` ) 
) <40
THEN @szamol := @szamol + LENGTH( `Comment` ) 
ELSE @szamol := LENGTH( `Comment` ) 
END b
FROM `comment` WHERE @groupom=0
ORDER BY `Num` DESC
Viszont valamiért itt a WHERE nem akarja értelmezni a @groupom paramétert.
Mindig 0-nak értelmezi, mert ha 0-át írok, akkor az összes rekordot kiírja, ha mást, akkor nem talál semmit.
Mi lehet ennek az oka.
Próbáltam HAVING-el is, de úgy is semmi.
Ha az egész után egy másik SELECT-ben kiíratom a @groupom változót akkor érdeke módon benne van az utolsó oldal száma.
Tehát miért nem működik a WHERE-ben az ellenőrzés, mert akkor lehet meg lehetne egy SELECT-et spórolni.

Előre is köszi.
Üdv:
Zoli
8

a where után értékelődik ki

Hodicska Gergely · 2008. Szep. 12. (P), 04.22
"In a SELECT statement, each expression is evaluated only when sent to the client. This means that in a HAVING, GROUP BY, or ORDER BY clause, you cannot refer to an expression that involves variables that are set in the SELECT list."

A WHERE is ebbe a kategóriába esik, így marad az, hogy subquery-be teszed, és a külső queryben szűrsz.


Üdv,
Felhő
9

kár

world-s · 2008. Szep. 12. (P), 09.52
Szia!

Tehát ha jól értem a CASE WHEN-en belül bár tudom mind a @szamol mind pedig a @groupom változót figyelni , elemezni, viszont a WHEN részben ezen változókra nem hivatkozhatok. Vagyis igen, de a teljes SELECT lefutásáig a kezdőértéket fogom bennük látni.

:(
Akkor ezek szerint max az oldalak számának meghatározásánál tudom így használni amikor is elég a végén megtudnom, hogy a @groupom változó végül mekkora értéken állt meg.

Az egymásba ágyazott SELECT futásilag mennyit jelent terhelés és idő szempontjából?

Esetleg a két CASE WHEN-t nem lehetne valahogy kiváltani úgy, hogy csak egy feltételvizsgálat legyen? Igazából a @groupom-ra van csak szükségem, a @szamol-t elég ha csak számolja. Csak nem tudtam azt megoldani, hogy két műveletet tudjak elvégezni egyszerre.

Előre is köszi.

Zoli