JOIN jedné tabulky víckrát kvůli různým podmínkám
- sKopheK
- Člen | 207
Nette 2.1dev
\Nette\Database
Tabulky
team: id, title
team_user: id_team, id_user
Potřebuju vytáhnout tým, který má přesně a jen a pouze dané členy.
Dle mě tedy najoinovat vícekrát (počet členů -krát) tabulku
team_user
a každému joinu předat jinou podmínku (id
člena).
Poradí někdo, jak toho dosáhnout v \Nette\Database
?
- sKopheK
- Člen | 207
SQL dotaz, který funguje podle představ, pro např. uživatele s
id
1 a 5 – tzn. chceme týmy, které mají členy s id 1 a
5 a žádné jiné.
SELECT team.*, COUNT(`team_user`.id_user) AS cnt
FROM `team`
JOIN `team_user` ON `team_user`.id_team = `team`.id
JOIN `team_user` user0 ON `user0`.id_team = `team`.id AND `user0`.id_user = 1
JOIN `team_user` user1 ON `user1`.id_team = `team`.id AND `user1`.id_user = 5
GROUP BY `team`.id
HAVING cnt = 2
- petr.pavel
- Člen | 535
Zbytečně joinuješ user0 a user1, filtrovat můžeš i bez nich.
V NotORM (NDB má syntaxi hodně podobnou):
$teamy = $this->db->team()
->select('team.*, COUNT(team_user:id_user) AS cnt')
->where('team_user:id_user', array(1,5))
->group('team.id', 'cnt = 2');
- petr.pavel
- Člen | 535
Už vidím, že ten můj dotaz by nefiltroval stejně (tj. máš pravdu), ale pořád si myslím, že ten tvůj je zcestný.
Tvůj dotaz začne tím, že spojí team a team_user, bez ohledu na hodnotu team_user.id_user. Takže když má tým dva uživatele, ve výsledku bude 2×. Když pět uživatelů, tak 5×.
Do toho pro id_user 1 a 5 znásobíš počet řádek, takže když měl předtím 2 řádky, teď má 2×2. Když měl 6, má 6×6. Když id_user není 1 ani 5, tak nadále zůstává původní počet řádek, protože tam není vazba z user0 na team_user (bez aliasu), takže původní počet řádek se neredukuje.
A nakonec odfiltruješ ty, které mají jen dva řádky. Což může být proto, že měli dva členy a žádný z nich nebyl 1 nebo 5, nebo že byly 1 nebo 5, ale současně taky měly jen jednoho člena.
Prostě blbost. Doporučoval bych nejdřív odladit ten dotaz a pak teprve dumat nad jeho převedením do NDB.
Ale taky se můžu plést. Můžeš mi říct, čeho se snažíš tím dotazem docílit?
- sKopheK
- Člen | 207
Nemůžu ti bohužel, co se týče teorie, příliš oponovat, protože jsem
tohle všechno buď nikdy nevěděl, nebo už zapomněl. Můj dotaz funguje
přesně tak, jak potřebuju, ale budu samozřejmě rád za nějaké
„hezčí“ řešení. První „neparametrizovaný“ JOIN
by se
dal přesunout až nakonec. Jinak jsem to hodil na http://stackoverflow.com/…fied-members, třeba někdo
s něčím přijde.