Jak spočítat počet příspěvků když mám tři tabulky?
- Pilda
- Člen | 52
Dobrý večer,
programuji svojí první aplikaci v nette, je to fórum a už dva dny si lámu
hlavu jak docílit toho, abych vypsal na úvodní stránku počet příspěvků
u každé kategorie. Kdybych používal jenom dvě tabulky, tak by to bylo
snadné ale se třemi si nevím rady.
Pro výpis počtu vláken v jednotlivých kategoriích jsem použil jednoduché {$category->related(‚forum_threads‘)->count()}, ale u těch příspěvků je potřeba se prokousat ještě třetí tabulkou a to nevím jak jednoduše udělat. Mohl bych zkusit to nějak složitě spočítat třeba procházením všech záznamů v tabulce, ale to mi moc elegantní nepřijde, asi by to dost zatěžovalo server.
Je možné to nějak elegantně spočítat a vypsat, nebo bude lepší ten počet akorát ukládat do tabulky, měnit a pak akorát posílat na výstup?
- hrach
- Člen | 1838
nicmene to provede pro kazdou kategorii dalsi select na count, nejlepsi bude:
$categories = $conn->table('forum_categories')
->select('forum_categories.*')
->select('COUNT(DISTINCT forum_threads:forum_posts:id) as postCount')
->group('forum_categories.id');
foreach ($categories as $category) {
echo "name: $category->name".
"count of posts: $category->postCount";
}
Editoval hrach (26. 12. 2011 23:40)
- bojovyletoun
- Člen | 667
Všiml jsem si dvojtečky v zápisu tabulek, mohl by to prosím někdo přidat do
dokumentace? Ze zdrojáku jsem si všiml, že jde o zpětné reference (many,
referencing,…). Co by tedy dělal dotaz, kdyby tam bylo
forum_threads:forum_posts.id
?
Hrachovi chci taky poděkovat za velké vylepšení nette database
Editoval bojovyletoun (27. 12. 2011 0:11)
- Pilda
- Člen | 52
Píše mi to chybu
PDOException #42000
SQLSTATE[42000]: Syntax error or access violation: 1064 You have an
error in your SQL syntax; check the manual that corresponds to your MySQL server
version for the right syntax to use near ‚:forum_posts:id) as postCount FROM
forum_categories
GROUP BY `forum_categories‘ at line 1
Není tam někde nějaký překlep, nebo něco? Nette používám verzi 2.0 betta 2.
Pro jistotu uvádím přesný zápis:
Presenter:
<?php
public function renderDefault() {
$this->template->categories = $this->getService('model')->getForumCategoriesTable()
->select('forum_categories.*')
->select('count(DISTINCT forum_threads:forum_posts:id) as postCount')
->group('forum_categories.id');
}
?>
Šablona
<table>
<tr><th>Kategorie</th><th>Téma</th><th>Přís.</th></tr>
{foreach $categories as $category}
<tr>
<td><a n:href="Category $category->id">{$category->name}</a><br>{$category->description}</td>
<td>{$category->related('forum_threads')->count()}</td>
<td>{$category->postCount}</td>
</tr>
{/foreach}
</table>
Editoval Pilda (27. 12. 2011 0:53)
- hrach
- Člen | 1838
@bojovyLetoun:
- jo, do dokumentace to samozřejmě všechno chci dát… :)
- zpětné joiny (aka join ve smyslu hasMany) je port z notorm, bohužel taky ne příliš zdokumentovaný a přidán v podstatě na moji zmínku právě ve stejném případu, jako řeší @pilda.
- ta syntaxe, co si popsal
forum_threads:forum_posts.id
je velmi zajimavý oříšek, který jsem se už taky zabýval. Jde to, že parser teď vždy vezme „token“ s tím symbolem, tedy „forum_threads:“, „forum_posts:“ a podle toho uděla ten join, muselo by se to tedy změnit na „:forum_threads:forum_posts“, což už by dávalo větší smysl i naznačením, že je to obráceně, ale zase tam není (a ono je to tak asi i názornější) ten sloupec id, což na druhou stranu může někoho zase mást oproti klasickému zápisu…
@Pilda
jo, to bude ten problém, že v betě 2 to ještě nebude implementované.
- hrach
- Člen | 1838
@pilda
jo a zkus pak jeste toto, aby se nedelal dalsi dotaz:
$this->template->categories = $this->getService('model')->getForumCategoriesTable()
->select('forum_categories.*')
->select('count(DISTINCT forum_threads:forum_posts:id) as postCount')
->select('count(DISTINCT forum_threads:id) as threadCount')
->group('forum_categories.id');
<td>{$category->threadCount}</td>
- hrach
- Člen | 1838
stahni tu dole nightly build: https://nette.org/cs/packages
pokud to stale nepojede, posli chybu a zkontroluj preklpy atp.
- Pilda
- Člen | 52
Paráda, už mi to jde, díky!
Akorát mi s tím night buildem přestalo fungovat vypsání příspěvků. Píše mi to chybu htmlspecialchars() expects parameter 1 to be string, object given. Píše mi to když chci vypsat datum příspěvku. Došlo tam od té bety 2 k nějakým zásadním změnám?
Editoval Pilda (27. 12. 2011 22:08)
- boob
- Člen | 21
mne len napadlo, ze by bolo mozno lepsie pridat do tabulky s kategoriami stlpec, kde by bol ulozeny pocet prispevkov a do tabulky s prispevkami pridat trigger, ktory by pri kazdom pridany/zmazani prispevku toto pocitadlo zmenil, aby to nebolo treba ratat vzdy pri kazdom nacitani stranky