[Doctrine] Requête select imbriquée dans un where not in
Messieurs dames,
soit une hiérarchie de catégories. Chaque catégorie peut avoir plusieurs parents et plusieurs enfants.
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
|
Category:
columns:
tag:
type: string(20)
CategoryHasCategory:
columns:
child_category_id:
type: integer
primary: true
notnull: true
parent_category_id:
type: integer
primary: true
notnull: true
relations:
ParentCategory:
class: Category
local: parent_category_id
foreignAlias: LinksToChildrenCategories
ChildCategory:
class: Category
local: child_category_id
foreignAlias: LinksToParentCategories |
Je cherche la liste des catégories racines, donc les catégories qui ne sont pas présentes dans CategoryHasCategory en tant que catégories filles. En SQL, facile :
Code:
select * from Category where id not in (select distinct(child_category_id) from CategoryHasCategory)
Malheureusement, Doctrine ne l'entend pas de cette oreille :
Code:
1 2 3 4 5 6 7 8 9
|
public static function getRootCategoriesQuery(Doctrine_Query $q = null) {
if(!$q) {
$q = self::getInstance()->createQuery();
}
$rootAlias = $q->getRootAlias();
return $q->andWhere("$rootAlias.id NOT IN(SELECT CategoryHasCategory.child_category_id FROM CategoryHasCategory)");
} |
donne comme code SQL généré par Doctrine :
Code:
1 2 3 4
|
$q = CategoryTable::getRootCategoriesQuery()->execute();
---> SQL généré :
SELECT c.* FROM category c, category_has_category c2 WHERE (c.id NOT SELECT c2.child_category_id FROM CategoryHasCategory IN ()) - () |
N'importe quoi, donc...
Je vais provisoirement contourner le problème en construisant le tableau des ids des catégories filles et en le passant au addWhere en argument, ce qui élimine la requête imbriquée. Mais ce qui m'intéresserait serait plutôt de construire le DQL avec requête imbriquée pour que Doctrine le comprenne.