Agregační podmínka na jinou tabulku
- nanuqcz
- Člen | 822
Ahoj,
dejme tomu, že bych chtěl z DB získat všechny kategorie, které obsahují
nějaké itemy.
Bohužel dotaz
$database->table('category')->where('COUNT(item:id) > 0');
skončí chybou.
Zatím mám tedy toto:
$database->table('category')->where('id',
$database->table('item')->select('DISTINCT category_id')
);
ale víc by se mi líbilo, kdyby fungovala první možnost. Je chyba v Nette\Database, anebo na to jdu špatně?
Díky
Editoval nanuqcz (10. 6. 2012 16:16)
- nanuqcz
- Člen | 822
PDOException #HY000
SQLSTATE[HY000]: General error: 1111 Invalid use of group function
SELECT `category`.*
FROM `category`
INNER JOIN `item` ON `category`.`id` = `item`.`category_id`
WHERE (COUNT(`item`.`id`) > 0)
Tvůj dotaz vyhodí trochu jinou chybu:
PDOException #42S22
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'count' in 'where clause'
SELECT COUNT(`item`.`id`) AS `count`
FROM `category`
LEFT JOIN `item` ON `category`.`id` = `item`.`category_id`
WHERE (`count` > 0)
což už nechápu vůbec, protože podle mě to SQL vypadá vpořádku.
- Tomáš Votruba
- Moderator | 1114
COUNT je myslím rezervovaný výraz (jako ORDER), zkus třeba
item_count.
Editoval Schmutzka (10. 6. 2012 17:34)
- Nifty
- Člen | 45
Rezervovaným výrazem to není. Na alias nelze použít podmínka WHERE (teda alespoň v MySQL). Nedávno jsem to taky řešil ve svém Gridu a nakonec na alias používám podmínku HAVING.
V Nette\Database to lze provést takto
$database->table('category')->select('COUNT(item:id) AS count')->group(NULL, 'count > 0');
- llook
- Člen | 407
Nejdřív se provede výběr podle WHERE a na něm se teprve provádí agregační funkce (COUNT). Jinak jestli chceš vybrat všechny kategorie, které mají alespoň jeden příspěvěk, tak udělej RIGHT JOIN a potom GROUP BY:
SELECT *
FROM `category`
RIGHT JOIN `item` ON `category`.`id` = `item`.`category_id`
GROUP BY `category`.`id`
Jak to zapsat v Nette\Database ale teď nevím.
- Nifty
- Člen | 45
Nějak jsem zapomněl, že tam používá agregační funkci. V tom případě ve group nebude NULL, ale
$database->table('category')->select('COUNT(item:id) AS count')->group('category.id', 'count > 0');
(jinak HAVING funguje i bez GROUP BY, pokud se použije alias například na duplicitní název sloupce v připojené tabulce)
Editoval Nifty (10. 6. 2012 19:51)