si si, j'ai juste supprimé la référence à la table supplémentaire et le addSelect qui y était lié.
Version imprimable
si si, j'ai juste supprimé la référence à la table supplémentaire et le addSelect qui y était lié.
si tu vois dans ça :
ce que tu as écrit ici :Code:
1
2
3
4
5
6
7
8
9
10
11
12 $q=$this->createQuery('a') ->select('a.*,sf.*,se.*,ga.id,a1.*,hi1.*') ->addSelect('hi2.total as prevtotal') ->leftJoin('a.users sf') ->leftJoin('sf.Costcenter se') ->leftJoin('sf.groupassets ga') ->leftJoin('ga.listGroupAsset a1 ON a1.groupasset_id=ga.id AND a1.type="email"') ->innerJoin('a1.historic hi1 ON hi1.asset_id=a1.id AND hi1.datestate="'.$datelimit.'"') ->leftJoin('a1.historic hi2 ON hi2.asset_id=a1.id AND hi2.datestate="'.$predate.'"') ->where('a.id=?',$site->getId()) ->andWhere('sf.is_active=true') ->orderBy('se.business, se.name, sf.last_name, sf.first_name')
Je veux bien que tu me le montre.Code:Doctrine_core::getTable('email_diskspace')->findOneByAssetIdAndDatestate($asset->getId(), $prevDate);
En plus la tu as exactement les meme jointure :
Pour une écriture plus lisible tu devrais mettre les and dans le where.Code:
1
2 ->innerJoin('a1.historic hi1 ON hi1.asset_id=a1.id AND hi1.datestate="'.$datelimit.'"') ->leftJoin('a1.historic hi2 ON hi2.asset_id=a1.id AND hi2.datestate="'.$predate.'"')
la relation a1.historic hi2 correspond a la relation entre la table asset et la table email_diskspace:
et pour: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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52 asset: tableName: asset actAs: [Timestampable] columns: type: string(50) value: string(255) groupasset_id: integer etat: string(50) action: string(50) chargebycsc: boolean in_use: boolean lastview: date indexes: unique1: fields: [type,value,groupasset_id] type: unique valueindex: fields: [value] lastview: fields: lastview: sorting: DESC relations: group: class: groupasset local: groupasset_id foreign: id foreignAlias: listGroupAsset onDelete: SET NULL email_diskspace: columns: datestate: date asset_id: integer specialaccount: string(50) total: integer billable_euro: float(5,2) billable_act: float(5,2) snapshot_annual_act: float(7,2) billable_adj: float(5,2) snapshot_annual_adj: float(7,2) indexes: unique: fields: [datestate, asset_id] type: unique relations: asset: class: asset local: asset_id foreign: id foreignAlias: historic
ce n'est pas la même jointure puisque $datelimit (=mois en cours) et $predate(mois précédent) ne sont pas les même :)Code:
1
2
3 ->innerJoin('a1.historic hi1 ON hi1.asset_id=a1.id AND hi1.datestate="'.$datelimit.'"') ->leftJoin('a1.historic hi2 ON hi2.asset_id=a1.id AND hi2.datestate="'.$predate.'"')
Et si je met le critere dans le leftjoin et non dans le where c'est que j'ai besoin d'avoir la ligne même si pas de données dans cette table.
bon je me permet de relancer cette discussion vu que ce n'est toujours pas résolue et que je traine ce problème sur pas mal de requête.
J'ai une nouvelle requete pas franchement compliqué:
qui me donne cet SQL:Code:
1
2
3
4
5
6
7
8 $q=Doctrine_Core::getTable('sfGuardUser')->createQuery('sf') ->select('cc.business as activite, a.special as special, count(a.id) as count') ->leftJoin('sf.Costcenter cc') ->leftJoin('sf.groupassets g') ->leftJoin('g.listGroupAsset a ON a.groupasset_id=g.id AND a.type="RAS MP" AND a.in_use=true') ->where('sf.is_active=true AND sf.site_id=12') ->groupBy('cc.business, a.special') ;
la pas de souci tout fonctionne.Code:SELECT c.business AS c__0, a.special AS a__1, COUNT(a.id) AS a__2 FROM sf_guard_user s LEFT JOIN costcenter c ON s.costcenter_id = c.id LEFT JOIN groupasset g ON s.id = g.user_id LEFT JOIN asset a ON ((a.groupasset_id = g.id AND a.type = "RAS MP" AND a.in_use = 1)) WHERE (s.is_active = 1 AND s.site_id = 12) GROUP BY c.business, a.special
ce que je désire est pas compliqué, puisque que au minimum je veut un truc du style:
quelqu'un a t il une idée de l'hydratation que je doit faire pour l'obtenirCode:
1
2
3
4
5 foreach ($data as $line) { echo $line['business'].' '.$line['special'].' '.$line['count'].'<br>'; }
J'avoue que ta question me laisse perplexe car chez moi, avec Doctrine 1.2 + sf 1.4, une requête similaire ne fonctionnera pas : la requête est créé sur la table sfGuardUser mais aucun champ de cette table ne figure dans le select et ça contrarie Doctrine qui lance une exception. Comment fais-tu pour que ta requête soit acceptée ???? 8O
J'ai aussi peut-être raté une étape dans ta problématique mais... si tu rédiges tes requêtes à la main sans passer par les câblages de Doctrine, pourquoi ne pas le faire jusqu'au bout en attaquant directement la couche PDO qui est sous Doctrine ? Par exemple (requête bidon, je te laisse adapter à ton cas) :
Code:
1
2
3
4
5
6
7 $statement = Doctrine_Manager::getInstance()->connection(); $results = $statement->execute("SELECT sf.*, cc.* FROM sf_guard_user sf LEFT JOIN sf_guard_user_profile cc ON cc.user_id = sf.id"); $coll = $results->fetchAll(Doctrine_Core::FETCH_ASSOC); foreach($coll as $row) { $profile = $row['phone_number']; }
Il est possible que la différence de réponse entre vous deux soit liée à une différence dans la structure du schéma de la base...
effectivement concernant ma requete j'aurai pu ne pas partir de sfGuardUser mais plutot de ma table asset, ce qui m'aurait permis de ne pas surcharger ma relation
et faire un leftJoin inversé.Code:->leftJoin('g.listGroupAsset a ON a.groupasset_id=g.id AND a.type="RAS MP" AND a.in_use=true')
Mais le souci de l'hydratation reste entier