Mysql pořadí řádku v dotazu
Často se Vám může hodit údaj o pořadí řádku ve výsledku dotazu, např. pro různé statistiky a pořadníky soutěží, výsledkové listiny apod., ale hodit se bude i pro jiné úkoly jako zjištění dalšího záznamu, aniž bychom museli procházet tisíce záznamů v aplikační vrstvě.
Mysql a uživatelské proměnné
Poslouží nám k tomu uživatelské proměnné v mysql. Tady je jednoduchý příklad jak vypsat seznam řádků včetně jejich pořadí v dotazu.
- SET @poradi:=0;
- SELECT @poradi:=@poradi+1, @poradi as poradi, id, name FROM table ORDER BY `name` DESC;
Výhodou je použití různých podmínek pomocí specifikace WHERE, GROUP BY atd., v takových případech je tato funkce nedocenitelná.
Jak zjistit kolikátý řádek vyhovuje podmínce?
Snadné, ale dalo mi to zabrat, než jsem se k tomu dobral :-). K čemu je to dobré? No tak si vezměte příklad: Představte si, že máme stránku detailu hráče na serveru o sportovních výsledcích a chceme zjistit, kolikátý je v pořadí na počty střel, asistencí, v počtu milenek apod.
- SET @poradi:=0,@poradib:=0;
- SELECT @poradi:=@poradi+1, @poradi as poradi, IF(id=201, @poradib:=@poradi, 0), id, name FROM table ORDER BY `name` DESC;
- SELECT @poradib;
Výsledkem je číslo označující pořadí. Samozřejmě si můžeme zvolit řadu podmínek, např. jen hráči české národnosti apod. Když provádíte takových porovnání 10 na jedné stránce, tak není jiné východisko, určitě je to vhodnější než provádět takové porovnání na aplikační vrstvě.
Co třeba přechod na předchozí a další článek?
Pokud nejsou identifikátory souvislé a jsou mezi nimi mezery (1,2,5,6 atd.), nebo se na ně nemůžeme spolehnout, bude se nám hodit zjistit identifikátor následující po určitém záznamu nebo identifikátor záznamu předcházejícího.
- SET @poradi:=0,@poradinow:=0, @idnext:=0, @idprev:=0;
- SELECT @poradi:=@poradi+1, IF(id=201, @poradinow:=@poradi, 0) FROM table ORDER BY `name` DESC;
- SET @poradi:=0;
- SELECT @poradi:=@poradi+1, IF(@poradinow-1=@poradi, @idprev:=id, 0), IF(@poradinow+1=@poradi, @idnext:=id, 0) FROM table ORDER BY `name` DESC;
- SELECT @poradinow, @idnext, @idprev;
Výsledkem je vrácení pořadí záznamu s ID číslem 201 a jeho předcházející a další prvek. Osobně tento dotaz provádím až ve chvíli, kdy ho opravdu potřebuji. Tedy odkazy na předchozí a nadcházející článek aktivují funkci vyhledání pořadí a zjištění okolních článků, pak se teprve přesměruje na správnou stránku.
Samozřejmě kvůli SEO by bylo vhodné odkazy uzavřít do formuláře nebo odkaz opatřit atributem rel="nofollow", aby další články nebyly indexovány pod url http://www.stranky.cz/nejaky-clanek/next, nebo aby nedocházelo k duplicitám, kde vyhledávače pak článek vidí pod dalšími třemi adresami.
podobné články
| 06.04.2008 | Mysql pořadí řádku v dotazu, druhý díl, problém pořadí zpracování uživatelských proměnných | (100%) |
komentáře
RSS Komentáře
Problém je hlavně v tom, že abych znal název předchozího a příštího článku musel bych provést ten dotaz už při výpisu aktuálního článku. Snažím se šetřit nároky na železo tím, že se dotaz provádí až, když je potřeba. Nemyslím, že je tento dotaz příliš složitý, ale v dalším díle už je to něco jiného.
Mel bych jeste jeden figl ktery by mohl byt rychlejsi..
Zjoinovat tabulku se sama sebou a a do WHERE dat podminky a do SELECTU COUNT(*) + 1 a dostaneme to same, rychlostne mozna lepsi … akorat Spojojovani tabulky se sama sebou dost casto lidi nechapu
Oky snad neco sesmolim az nebudu mit frmol ve worku [http://www.rjwebdesign.net/Blog]
Jinak pochvala, zajimave ctivo ( obzvlast sekce MYSQL )
Jinak by me zajimalo jak to bude s rychlosti
1. SET @poradi:=0,@poradib:=0;
2. SELECT @poradi:=@poradi+1, @poradi as poradi, IF(id=201, @poradib:=@poradi,
0), id, name FROM table ORDER BY name DESC;
3. SELECT @poradib;
Porad to jsou 3 dotazy, kdyz budu mit na strance treba 5 tabulek ⇒ 15 dotazu , jak to bude rychle?
Predpokladam ze dotaz na nastaveni poradi bude pro server zanedbatelny nebo se pletu?
určitě zanedbatelný, první je nastavení uživatelské proměnné (nemá vliv na rychlost), poslední je vypsání obsahu uživatelské proměnné (nemá vliv na rychlost)
předpokládám, že na jedné stránce nebude 5× stránkování nebo prostě výpis 5× nějakého seznamu, kde by byl vhodný přechod na další záznam nebo ano? pokud ano určitě bych to rozdělil na více stránek
Jasne, ja si akorat rikam ze musi projet vsechny radky v DB ( resp podle SQL dotazu ) aby je ocisloval a ja na mem hernim portalu [http://www.pesonline.cz] pouzivam ruzne praktiky, nekde je rychle to jinde zase ono.
( Kesovani SQL dotazu, ocislovani radku po updatu natvrdo atd ..)
Uvital bych RSS a vice clanku z MYSQL :) , napriklad na tuto tematiku [http://www.rjwebdesign.net/…love-Tabulky]
očíslování řádku bohužel nelze použít na různé filtry, výhodou tohoto je možnost použít i přeskakování na další a předchozí články dle parametrů vyhledávání! běžně to používám v systémech, kde je až 20 parametrů vyhledávání a více než 100 000 položek, zatím to jede svižně :), každopádně třeba uvedu příklad, kde si to jinak nedokážu představit: články jsou filtrovány podle kategorie, osoby která vložila články, a textu který obsahují, přesto výsledek tvoří např. 1000 článků, a nyní potřebujeme jejich překlady, tlumočník, jen píše překlad a kliká na další článek, žádné zdržování s přecházením na seznam článků apod.,
RSS – je ve spodu stránky, jestli myslíš RSS diskusí, tak ano brzy bude, stejně tak odesílání nových příspěvků na mail
jinak co se týče odkazu zkus formulovat více svůj zájem, jsem autorem www.nhlpro.cz z této problematiky mám několikaleté zkušenosti, v rámci časových možností by mohlo něco více přibývat :)
Heh, tak to jsme se spolu uz asi bavili, s nekym z NHLPRO jsem se bavil a ted nevim kdo to byl :) // cca 3–6 mesicu zpet /
Zrovna se mi libilo http://www.nhlpro.cz/hraci/hrac.php?…
ze v teto osobni karte hrace vidim kolikaty v zebricku je treba v golech , nahravkach atd .. ale to asi resi toto ze? –
Jinak by me z nhlpro.cz zajimala asi tak 1/3 vsech skriptu .. :) napriklad jakym stylem se generuji tabulky
http://www.nhlpro.cz/tymy/poradi.php?…
http://www.nhlpro.cz/tymy/poradi.php?…
Co vsechno se tam kesuje, jakym stylem. Urcite i teoreticke uvahy o tom jak ukladat data i reduntantne aby se potom tolik nezatezovala databaze …
Sry za rozepsani, vidim spriznenou dusi ( statistiky, tabulky a to je moje viz jiz jednou zminovany )
No budu se tesit :)
no co se tyce nhlpro, je tam 10k navstev denne v sezone, ale zklamu tě, přesto že mám plán co kešovat a jak postupovat s projektem dále, jsem jen programátor, o těchto věcech rozhoduje manažer, v sezóně jsme měli hodně problémy, co se týče návštěvnosti, byla tak vysoká, že to server nedokázal obsloužit a díky tomu zbytečně server přicházel o návštěvnost, v současné době už dlouhodobě jednáme o možných změnách, takže nebudu prozrazovat více ze zákulisí, každopádně když položíš konkrétní dotazy jsem ochoten zpracovat v rámci možností článek s odpověďmi
To je v poradku, mam taky svoji kesovaci tridu a ze je velmi dobra :) ( kesovani SQL do pameti ..)
Me by spis tedy nez kesovani zajimalo to co jsem napsal v predchozim komentari.
Tesil bych se ne nejaky mensi serial clanku o tom jak pocitat sportovni tabulky a statistiky obecne ( nemusi to byt dopodrobna ) , tak aby nebyl problem se zatezi ani pracnosti.
Tabulky, statistiky … atd Mam te v RSS tak se budu tesit.
Co takhle si napsat kokrétní věci co by tě zajímali, nevím jestli by takový seriál krom tebe někoho zajímal?
Třeba nadpisy článků a tak? Zajímá tě programování nebo počítání statistik? Krom toho si myslím, že půjde o hokej jiné sporty jiné výpočty.
Mno ono vseobecne moc lidi toto nezajima, nebo tedy nevim o nikom kdo by se tolik vyzival ve statistikach a tabulkach ve sportu.
Napsat konkretni veci samozrejme muzu, ale ma cenu si takhle psat do komentaru? Co treba nekdy na ICQ, treba bych Ti predal i ja cosi.
Jinak nechapu, nadpisy clanku ?
>> Zajímá tě programování nebo počítání statistik?
Programovani ani tolik snad ne, kazdy ma vlastni styl psani kodu atd ale spis ten zpusob jak to rozdelit / cili vykon a umisteni dat aby to bylo v dobrem pomeru a dalo se z toho vse vytahnout .. /
Jestli se Ti do toho nechce np, nejsem zvykly otravovat
Kontakt na Tebe nemam, muj je na www.rjwebdesign.net/Kontakt
Pekny vikend
přiznám se, že sem dlouho hledal řešení, tohle vypadá jednoduše, proto je mi divné, že bych na to nepřišel, zkusím v rámci času přes týden projít, proč jsem to neřešil takhle, dej sem odkaz na nějaký tvůj blog nebo něco pokud máš
jinak proč nesmyslně? rozhodně to funguje
tak už tuším proč jsem to nepoužil:
- goly se v tabulce pocitaji za zapasy, takže je nutné použít sum() a taky group by IDhrace, pak by count(*) neměl smysl, protože by počítal jen výskyty toho hráče
- zjednodušením vznikl tento článek, každopádně mne teď nenapadá problém proč nepoužít to co píšeš, snad jen, že je nutný druhý subselect, což v mém případě není nutné
- otázka je co nabízí více možností, např. příští článek a předchozí článek? jak třeba pomocí metody „Kajman“ vypsat článek v pořadí 351?
- vařím z vody není moc čas, tak doufám, že mé závěry jsou správně, ale třeba se mýlím, každopádně proč zavrhovat mou metodu? její nevýhodu vidím v tom, že musí projít cyklem úplně všechny řádky, což by mohl být problém! ale jinak, šlo o to jak pomocí uživatelských proměnných počítat pořadí řádku a pak s ním manipulovat, Kajman metoda šikovně obchází smysl
To není metoda „Kajman“, následující, další mi takhle kdysi taky někdo poradil. Je to jednoduché rychlé řešení. Mohou se vracet klidně všechny sloupečky a oba směry lze spojit přes union, takže stačí jeden jediný dotaz.
A limit 350,1 vypíše 351. řádek – žádné složitosti
metoda kajman pracovní označení :), neřekl jsem, že je to blbost, proč ne, jsou to dva složené dotazy to při mém řešení není nutné přece?
proč hned odsuzuješ použití uživatelských proměnných?co je na tom složitého? myslíš, že je nastavení uživatelské proměnné nějak náročné?nebo dotaz na získání uživatelské proměnné?
Pokud máme seznam u kterého se chceme pohybovat PREV a NEXT směrem seřazený podle čísel (klidně i v nesouvislé řadě) nebo času, tak toto je zbytečný kanón na vrabce. Je to v článku jen povrchně zmíněno a zasloužilo by to více zdůraznit, než to někdo jen bezmyšlenkovitě zkopíruje. Pokud chci další článek po článku s id=201, tak to jednoduše udělám následovně: SELECT * FROM clanky WHERE id > 201 ORDER BY id LIMIT 1
U řazení podle času to bude fungovat stejně spolehlivě. Věřím, že by to fungovalo i s textem, ale tam už by to zavánělo magií.



Já bych opatřil noindex hlavě tu stránku next. BTW: není pro vyhledávače nejlepší, když mají Předchozí článek Mysql poředí řádků v dotazu? Stejně to IMHO nezabere moc času.