Zadejte hledaný výraz...

Hledam řešení pro podobnou fci jakou má GROUP BY, ale ne presne stejnou

hm
verified
rating uzivatele
(20 hodnocení)
17. 12. 2011 07:34:37
Příklad:
tabulka
user_id
content_id
action
date
Dotaz s GROUP BY který varcí téměř co potřebuji:
SELECT * FROM tabulka GROUP BY content_id, action ORDER BY date DESC LIMIT 15
Problém
Dotaz v podstatě vrací data tak aby tam nebyla duplicita obsah/akce bez ohledu na to kdo akci udelal. Nicmene pokud tam budou tyto akce od uzivatele A pozdeji od uzivatele B a pozdeji od uzivatele C, s timto group by to vrati prvniho kdo tu akci udelal, tedy uzivatele A a ostatni vynecha, jenze jak je videt diky ORDER BY date DESC ja potrebuji vratit posledniho uzivatele ktery akci ucinil, nikoliv prvniho...
Moje řešení
Dělám dotaz bez GROUP BY, v php vyřadim duplicitní uživatele k záznamu a takhle opakuji dokud nevyberu 15 neduplicitních řádků.
ANO, toto řešení sice funguje, ale je uplně dementní, jenže jsem teď strašně přepracovanej a z nějakého důvodu prostě nemůžu vymyslet dotaz, který to vybere podle mé potřeby. Tak se tu obracím na vás.
Díky za každé nakopnutí
17. 12. 2011 07:34:37
https://webtrh.cz/diskuse/hledam-reseni-pro-podobnou-fci-jakou-ma-group-by-ale-ne-presne-stejnou#reply708121
Bacon
verified
rating uzivatele
(2 hodnocení)
17. 12. 2011 08:00:46
Ahoj,
nevím, jestli to dobře chápu a jestli ti to pomůže, ale pro vypsání neduplicitních dat slouží DISTINCT.
17. 12. 2011 08:00:46
https://webtrh.cz/diskuse/hledam-reseni-pro-podobnou-fci-jakou-ma-group-by-ale-ne-presne-stejnou#reply708120
hm
verified
rating uzivatele
(20 hodnocení)
17. 12. 2011 08:03:01
DISTINCT a DISTINCTROW je v podstate GROUP BY akorat ze k tomu navic nemuzu vybrat libovolne sloupce, jen ty co jsou v DISTINCT ... takze se obavam ze to nepomuze :(
---------- Příspěvek doplněn 17.12.2011 v 09:04 ----------
Tak po delsi dobe hledani a hrani jsem dosel k nasledujicimu dotazu ktery dela presne to co popisuji, nektere databaze to maji jako DISTINCT ON () ovsem to mysql nepodporuje, obchazi se to takto:
17. 12. 2011 08:03:01
https://webtrh.cz/diskuse/hledam-reseni-pro-podobnou-fci-jakou-ma-group-by-ale-ne-presne-stejnou#reply708119
Pokud čtu tvé zadání dobře, potřebuješ
http://stackoverflow.com/a/1313293/718951
17. 12. 2011 10:48:53
https://webtrh.cz/diskuse/hledam-reseni-pro-podobnou-fci-jakou-ma-group-by-ale-ne-presne-stejnou#reply708118
hm
verified
rating uzivatele
(20 hodnocení)
17. 12. 2011 10:56:14
Výborně díky, ta optimalizace se bude hodně hodit, sice sem to uz trochu optimalizoval pres where id>(*subquerty na vyber nejvetsiho id*)-1000 kdy sem to an tabulce s milionem zaznamu srazil ze 3 sekund na 30 milisekund, ale ten left join bude ais lepsi a mozna to optimalizuje jeste vic :)
---------- Příspěvek doplněn 17.12.2011 v 11:14 ----------
Jo tak varianta s left joinem strhla server, vysledek vraci spravne, ale jak se na stackoverflow nekdo zminoval, ten left join proste funguje rychlejc jen na malo zaznamech, jakmile je to ten milion tak jeho rychlost velice rapidne klesa, zustanu u optimalizovaneho subquery a 30ti milisekund :)
17. 12. 2011 10:56:14
https://webtrh.cz/diskuse/hledam-reseni-pro-podobnou-fci-jakou-ma-group-by-ale-ne-presne-stejnou#reply708117
Naopak, ten left join je rychlejší, pokud máš správný index (content_id, action).
17. 12. 2011 11:36:04
https://webtrh.cz/diskuse/hledam-reseni-pro-podobnou-fci-jakou-ma-group-by-ale-ne-presne-stejnou#reply708116
hm
verified
rating uzivatele
(20 hodnocení)
17. 12. 2011 11:44:20
nevim, zkus si to otestovat, ja to zkousel a na vysledek z left joinu jsem se pro jistotu vubec nedostal (proste to zasere mysql uplne do sracek a musim to retsratovat) a ano :) mam spravne indexy...
btw i subquery bez optimalizace je na te milionove tabulce na 2 sekundy (s optimalizaci 30ms), coz je porad mnohem rychlejsi nez ten left join co to uplne zasekne (ale funguje kdyz ma tabulka min zaznamu, ale rychlost hodne klesa s pribyvajicimi tisici zaznamu)
---------- Příspěvek doplněn 17.12.2011 v 12:10 ----------
jinak zkousel jsem i jina reseni z onoho tematu, zatim z toho porad vychazi nejlip ten subquery co sem uvadel tady... protoze ty ostatni sice funguji dobre na male tabulce, ale kdyz to dam na milionovou (a na te se to taky bude provozovat) tak jde vykon tech dotazu vetsinou do haje (jinak receno ani po 3 minutach nevraci vysledek = restartuji mysql) nebo se k subquery ani nepriblizuji (trvaji desitky sekund)...
17. 12. 2011 11:44:20
https://webtrh.cz/diskuse/hledam-reseni-pro-podobnou-fci-jakou-ma-group-by-ale-ne-presne-stejnou#reply708115
Určitě by se na zádrhel dalo přijít přes EXPLAIN, ale pokud ti to funguje uspokojivě se subquery, ok.
17. 12. 2011 15:02:12
https://webtrh.cz/diskuse/hledam-reseni-pro-podobnou-fci-jakou-ma-group-by-ale-ne-presne-stejnou#reply708114
hm
verified
rating uzivatele
(20 hodnocení)
17. 12. 2011 15:05:59
jo ja ten explain kontroloval a prave ze tam neni nic spatne, podle explain by clovek dokonce rekl ze subquery proste musi byt pomalejsi, ale s mym prekvapenim to tak neni... jeste se nabizi potencialne spatne nastaveni mysql (nemam to nijak vyladene pro velke vykony) coz muze zpusobovat, ze se left join provadi pres tabulky z disku nebo co ja vim... ale porad tam visi otaznik proc subquery jede bez problemu a left join v podstate odstavi server (resp. zbaere si pro sebe cele jedno jadro procesoru), kazdopadne je to tak no... dotaz na 30ms je uplne v pohode, takze to tak hold necham :)
17. 12. 2011 15:05:59
https://webtrh.cz/diskuse/hledam-reseni-pro-podobnou-fci-jakou-ma-group-by-ale-ne-presne-stejnou#reply708113
takatom
verified
rating uzivatele
(2 hodnocení)
18. 12. 2011 18:54:08
Takto používat group by je smrtící. Možná MySQL popisuje nějaké pravidlo, jak si domyslí, co si uživatel myslí, ale v normálním módu má nahlásit chybu. Zadání by mělo obsahovat celý script tabulky včetně indexů, i když tam indexy "jsou", je otázka, zda ty pravé.
Jak vlastně zní zadání?
zajímá nás a) posledních 15 dokumentů na kterých udělal někdo nějakou akci, nebo b) posledních 15 akcí na některých dokumentech?
a) select document_id,max(datum)as datum from tabulka group by document_id order by max(datum) desc limit 15
b) select document_idakce,max(datum)as datum from tabulka group by document_id,akce order by max(datum) desc limit 15
K tomuto základu se pak přidají zbylé informace pomocí JOIN (zásadně NE! LEFT JOIN)
Pokud jsou správné indexy, není online nic rychlejšího.
Pak zbývá otázka, jak moc jsou důležité tyto údaje, jestli to nestačí zjišťovat jednou za hodinu nebo za den...
18. 12. 2011 18:54:08
https://webtrh.cz/diskuse/hledam-reseni-pro-podobnou-fci-jakou-ma-group-by-ale-ne-presne-stejnou#reply708112
hm
verified
rating uzivatele
(20 hodnocení)
18. 12. 2011 19:03:36
informace se zjistuji presne jednou za dve sekundy... byo by vhodne mit dotaz maximalne optimalizovany, nicmene to uz jsem v podstate udelal, 30ms na neoc rpes milion zaznamove tabulce mi prijde dost v poradku
Zajima nas 15 poslednich akci na dokumentech, ovsem bez duplicit (pokud dva uzivatele udelaji stejnou akci na stejnem dokumentu, zobrazi se opuze akce toho kdo ji udelal posledni), v podstate to popisuje dotaz ktery jsem poslal hned v mem druhem prispevku - ten totiz vraci presne pozadovana data...
nicmene... tvuj dotaz trpi uplne stejnou veci - vraci prvni uzivatele co akci provedli, nikoliv posledni :) takze ej to nepouzitelne :) zustanu u moji verze, pokud tedy nemas navrh jak tvuj dotaz zmenit aby vracel poslendiho nikoliv prvniho uzivatele co akci provedl
martinuv left join sice vraic spravna data ale vykon toho dotazu dosahuje vykonu houpaciho kone
18. 12. 2011 19:03:36
https://webtrh.cz/diskuse/hledam-reseni-pro-podobnou-fci-jakou-ma-group-by-ale-ne-presne-stejnou#reply708111
takatom
verified
rating uzivatele
(2 hodnocení)
18. 12. 2011 20:10:36
Ve svém příspěvku jsem především brojil proti nestandardnímu group by. Osobně to považuji za chybu stejného kalibru jako neinicializovaná proměnná.
ano, b) byl můj favorit, ale uživatele je třeba získat jinak:
select document_id,action,max(date)as datum,
(select max(user_id) from tabulka tt where tt.document_id=t.document_id and tt.action=t.action and tt.date=max(t.datum))as uzivatel
from tabulka t group by document_id,action order by max(datum) desc limit 15
Je to prakticky ekvivalent Vašeho příkazu, jen doufám v (zanedbatelně) rychlejší vykonání.
V teoretickém krizovém scénáři (uživatel zaznamená více stejných akcí nad dokumetem v jednom časově měřitelném intervalu) můžete získat duplicity - předpokládáte unique(document_id,action,date)
Touto poznámkou brojím proti používání datetime jako klíčového údaje
18. 12. 2011 20:10:36
https://webtrh.cz/diskuse/hledam-reseni-pro-podobnou-fci-jakou-ma-group-by-ale-ne-presne-stejnou#reply708110
hm
verified
rating uzivatele
(20 hodnocení)
18. 12. 2011 20:44:16
jj v dotazu jsem uz datetime vymenil za ID zaznamu vcera, protoze se datum nijak nemeni a ID tak koresponduje s nim, jen tam nejsou ty duplicity datetimu ...
jinak vas dotaz vraci data prakticky stejne rychle/pomalu (jak se to vezme) jako dotaz co jsem napsal nahore a po optimalizaci kterou delam to v podstate taky kolisa kolem 30ti milisekund, takze ono je asi jedno jaky pouziju :) kazdopadne diky za venovany cas, dnesa vidim cely problem ponekud cisteji :))
18. 12. 2011 20:44:16
https://webtrh.cz/diskuse/hledam-reseni-pro-podobnou-fci-jakou-ma-group-by-ale-ne-presne-stejnou#reply708109
Pro odpověď se přihlašte.
Přihlásit