Avatar
Michal Kuba
Redaktor
Avatar
Michal Kuba:

Ahoj.
Mám na webu dejme tomu v tabulce článků přes 100 záznamů. Pak mám tabulku, kde se ukládá hodnocení článků (1-5 hvězd, ukládá se pouze číslo 1-5), a zde je přes 250 záznamů. Jsou články, který teď mají třeba 10 hodnocení různýho rozpětí, pak je třeba článek co má tři hodnocení jen nejlepší.

Chci udělat výpis nejlepších článků podle průměru hvězdiček. Mám tuto konstrukci:

SELECT clanky.*, AVG(stars.pocet) AS pocet
                   FROM clanky
                   INNER JOIN stars ON clanky.ID_clanek=stars.id_clanku
                   WHERE clanky.datum <= CURDATE()
                   GROUP BY clanky.ID_clanek
                   HAVING COUNT(stars.id_clanku)>3
                   ORDER BY AVG(stars.pocet) DESC
                   LIMIT 20

Průměry to vybírá dobře, řeším ale část "HAVING..". Když tam toto omezení nebylo, tak logicky na prvních místech jsou ty, které mají jediné hodnocení 5*. Je nějaká elegantní volba, jak nastavit místo té konstanty 3 něco (představuji si něco jako podělení sumy a počtu něččeho, ale nefunguje to), aby se reagovalo na počty hodnocení a fakt se ukazovaly ty nejvíc top články? Aby to prostě nebralo článek s jedním 5* hodnocením jako nejlepší? Je mi jasný, že když bude 10 000 hodnocení a budu vybírat články kde je alespoň přes 3 hodnocení, tak to bude vypisovat jako lepší výsledek než článek, který bude mít 1000 hodnocení, ale o nějakou desetinku horší než ten článek se 3 hodnoceními?

Díky :)

 
Odpovědět 31. října 22:00
Avatar
Odpovídá na Michal Kuba
Ondřej Štorc:

Ahoj,
co třeba si spočítat průměrný počet hodnocení na článek a použít to místo té konstanty?

Nahoru Odpovědět 31. října 23:01
Život je příliš krátký na to, abychom bezpečně odebírali USB z počítače..
Avatar
Petr Linhart
Člen
Avatar
Odpovídá na Michal Kuba
Petr Linhart:

A nešlo by to takhle?

SELECT clanky.*, AVG(stars.pocet) AS pocet
                   FROM clanky
                   INNER JOIN stars ON clanky.ID_clanek=stars.id_clanku
                   WHERE clanky.datum <= CURDATE()
                   GROUP BY clanky.ID_clanek
                   ORDER BY AVG(stars.pocet) DESC, COUNT(stars.id_clanku) DESC
                   LIMIT 20
 
Nahoru Odpovědět 4. listopadu 6:47
Avatar
Michal Kuba
Redaktor
Avatar
Michal Kuba:

Funguje mi to takhle:

SELECT clanky.*, AVG(stars.pocet) AS pocet
                   FROM clanky
                   INNER JOIN stars ON clanky.ID_clanek=stars.id_clanku
                   WHERE clanky.datum <= CURDATE()
                   GROUP BY clanky.ID_clanek
                   HAVING COUNT(stars.id_clanku)>(SUM(stars.pocet)/COUNT(stars.pocet))
                   ORDER BY AVG(stars.pocet) DESC
                   LIMIT 20
 
Nahoru Odpovědět 4. listopadu 7:58
Avatar
Petr Linhart
Člen
Avatar
Odpovídá na Michal Kuba
Petr Linhart:

Pokud se nepletu tak tvým filtrem projde článek s dvěma hodnoceními jednou hvězdičkou, zatímco článek hodnocený pětkrát pěti hvězdičkami neprojde. Takže si nejsem jistý jestli sem pochopil přesně o co ti původně šlo.

 
Nahoru Odpovědět 4. listopadu 10:28
Avatar
Michal Kuba
Redaktor
Avatar
Michal Kuba:

Zkusil jsem i tvůj filtr. Jenže to mi právě vybírá článek, který má jen dvě hodnocení s pěti hvězdami, takže když má článek přes 15 hodnocení a výsledek je dohromady kolem 4.3 tak je poměrně nízko.. To moje nastavení mi zatím vyhovuje, dává to podle mě dostatečně objektivní výsledky.

 
Nahoru Odpovědět 4. listopadu 10:39
Avatar
Petr Linhart
Člen
Avatar
Odpovídá na Michal Kuba
Petr Linhart:

Ano můj návrh řeší jen seřazení v případě, že průměr je shodný, pak platí, že vícekrát hodnocený článek je výš.

Neber to tak, že rýpu nebo poučuju je to jen otázka mé vlastní zvědavosti, ale co mi nejde do hlavy je následující případ:

  • řekněme že máš dva články, oba mají shodně 5 hodnocení a v obou případech se jedná o 5 hvězdiček
  • k prvnímu článku ti uživatelé udělí dalších 10 hodnocení všechna se 4 hvězdičkami
  • k druhému ti uživatel udělí jedno hodnocení s 2 hvězdičkami

Podle mě by tedy první článek měl být v seznamu výše, protože má v podstatě lepší hodnocení, jak na známky, tak na množství uživatelů.

Tvůj dotaz ti, ale vrátí:

id_clanek title pocet
2 Druhý článek 4,5
1 První článek 4,3333

Mám totiž divný pocit, že tohle není tak úplně objektivní seřazení.

 
Nahoru Odpovědět 4. listopadu 12:53
Avatar
Nahoru Odpovědět  +1 4. listopadu 20:49
while (!asleep()) sheep++;
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 8 zpráv z 8.