JOIN jedné tabulky víckrát kvůli různým podmínkám

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
sKopheK
Člen | 207
+
0
-

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
+
0
-

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
+
0
-

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');
sKopheK
Člen | 207
+
0
-

Tohle vybere i tymy, ve kterych je nekdo navic, protoze ten COUNT secte je „namatchovany“ uzivatele – ne vsechny, co se k tomu tymu vazou. Jinak druhy agrument metody group() je od 2.1 deprecated a melo by se pouzivat having().

Editoval sKopheK (22. 11. 2013 23:39)

petr.pavel
Člen | 535
+
0
-

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
+
0
-

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.