subselect pomoci Nette\Database

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

Zdravim.
Jakym zpusobem muzu pomoci Nette\Database udelat subselect „not in“. Priklad:
Dve tabulky:
role – ciselnik roli (id,nazev) a vazebni tabulka roleagenda (role_id,agenda_id)
Ja chci udelat neco takoveho:

`SELECT * FROM role WHERE id NOT IN (SELECT role_id FROM roleagenda WHERE agenda_id=1) `

Diky.

Oli
Člen | 1215
+
0
-

Mělo by jít něco jako viz. dokumentace:

$roleAgenda = $connection->table('roleagenda')->select('role_id')->where('agenda_id = ?', 1);
$connection->table('role')->where('id NOT IN ?', $roleAgenda);
JarekSt
Člen | 39
+
0
-

Oli napsal(a):

Mělo by jít něco jako viz. dokumentace:

$roleAgenda = $connection->table('roleagenda')->select('role_id')->where('agenda_id = ?', 1);
$connection->table('role')->where('id NOT IN ?', $roleAgenda);

Jo, funguje to. Dlouho se nikdo nehlasil, tak jsem to poresil pomoci connection->query, ale tvoje reseni je elegantnejsi. Diky moc.

David Matějka
Moderator | 6445
+
0
-

ten kod ale neudela subselect – nejdrive provede prvni dotaz a idcka pouzije do not in. na to si dej pozor…

duke
Člen | 650
+
0
-

Přesněji řečeno: To, zda se provede sub-select nebo ne, záleží na typu databáze. Pro MySql se skutečně nepoužije vnořený dotaz a sice z optimalizačních důvodů.

David Matějka
Moderator | 6445
+
0
-

@duke: diky, to jsem nevedel :) skoda, ze se ten subselect nenecha nejak vynutit. nekdy ta optimalizace nemusi byt zrovna vhodna..

Jan Tvrdík
Nette guru | 2595
+
0
-

@matej21: Máš nějaký příklad, kdy ta optimalizace není vhodá?

David Matějka
Moderator | 6445
+
0
-

treba kdyz by ten subselect (respektive nesubselect) mel vytahovat velke mnozstvi zaznamu a pak je skladat do IN

edit: tak jsem udelal rychlej test – kdyz se vybiraji id pro ten IN misto subselectu, tak to trva od nekolika desitek milisekund pro stovky zaznamu po stovky milisekund az sekundy pri par tisicich zaznamech.

edit2: odhalen nejvetsi zrout vykonu: https://api.nette.org/…der.php.html#261 pri nahrade za $arg[] = $row->{$clone->getPrimary()}; spadnul cas pro 5k polozek z 4s na 200ms :) jen nevim, jestli by to neco nekomu nemohlo rozesrat..

Editoval matej21 (12. 11. 2013 1:56)

saimons
Člen | 293
+
0
-

@matej21: Zkousel jsi nekdy pouzit tyto dva selecty pro nakej vetsi pocet? Me to v radech tisicu funguje na podprumernem VPS, ale obavam se toho az to naroste do radu desetitisicu. Jestli pak neni lepsi volit variantu s JOINen?