Hi Alex,
du hast Recht, dass es da Überschneidung gibt mit anderen Parametern, die in find verwendet werden können.
Du siehst den Unterschied, wenn du dir das erzeugte SQL-Kommando ansiehst. Nehmen wir als Beispiel mein Immobilien-Modell: Wenn ich anstatt dem CustomBehavior die Reduktion über fields vornehmen, sieht mein Aufruf als Beispiel wie folgt aus:
- Code: Alles auswählen
$eintraege = $this->Immobilien->find('all',array( 'fields' => array('immobilien.objektnummer', 'immobilien.plz', 'immobilien.ort', 'immobilien.strasse', 'immobilien.stichwort', 'anhaenge.pfad', 'anhaenge.gruppe'), 'group' => array('Immobilien.objektnummer') ));
Das erzeugte SQL-Kommando sieht dann so aus:
- Code: Alles auswählen
SELECT `immobilien`
.`objektnummer`
, `immobilien`
.`plz`
, `immobilien`
.`ort`
, `immobilien`
.`strasse`
, `immobilien`
.`stichwort`
, `anhaenge`
.`pfad`
, `anhaenge`
.`gruppe`
FROM `immobilien`
AS `Immobilien`
LEFT
JOIN `immobilienart`
AS `Immobilienart` ON
( `Immobilien`
.`immobilienart`
= `Immobilienart`
.`id`
)LEFT
JOIN `anhaenge`
AS `Anhaenge` ON
( `Anhaenge`
.`objektnummer`
= `Immobilien`
.`objektnummer`
)LEFT
JOIN `freitexte`
AS `Freitexte` ON
( `Freitexte`
.`objektnummer`
= `Immobilien`
.`objektnummer`
)WHERE
1 =1GROUP BY `Immobilien`
.`objektnummer`
So, und nun schau' dir (unten) den Screenshot aus phpMyAdmin dazu an, wenn ich das GROUP BY weg lasse. Du siehst, dass es jetzt keine Null-Einträge gibt, denn es sind alle Felder gefüllt, aber es gibt als Ergebnis jeden Eintrag zig-fach, da MySQL im Hintergrund die über das Modell verbundenen (aber nicht im Array fields enthaltenen) Tabellen immobilienart und freitexte berücksichtigt.
Du wirst, wenn du im Internet zum Thema Unbind und CustomBehavior recherchierst, einige Beiträge finden, in denen Anwender die Grenzen der Datenbank durch dieses autom. Einbinden gesprengt haben, da MySQL intern zuerst die Datensätze selektiert und erst dann durch GROUP BY verdichtet - sofern der Befehl mitgegeben wird.
Aber: einen Haken hat die Sache noch: Möchte man fields und CustomBehavior kombinieren, muss man "unnötige" rendundante Angaben machen. Ein funktionierender Aufruf, der sowohl die Felder des aufgerufenen Modell einschränkt, als auch die durch CustomBehavior sieht dann z.B. so aus:
- Code: Alles auswählen
$this->paginate['Immobilien'] = array( 'limit' => 5, 'conditions' => $conditions, 'recursive' => 0, 'fields' => array('Immobilien.objektnummer', 'Immobilien.plz', 'Immobilien.strasse', 'Immobilien.ort', 'Immobilien.gesamtpreis', 'Immobilien.stichwort', 'Immobilien.mietekauf', 'Immobilien.iso_waehrung', 'Immobilien.nettokaltmiete', 'Anhaenge.objektnummer', 'Anhaenge.pfad', 'Anhaenge.gruppe', 'Anhaenge.anhangtitel'), 'contain' => array( 'Anhaenge' => array( 'fields' => array('Anhaenge.objektnummer','Anhaenge.pfad','Anhaenge.gruppe','Anhaenge.anhangtitel') ) ), 'group' => 'Immobilien.objektnummer');
Das Ergebnis ist dann allerdings, dass man ein sehr sauberes SQL-Kommando hat, das sich auf das beschränkt, was man benötigt. Eben so, wie man es "von Hand" machen würde:
- Code: Alles auswählen
SELECT `Immobilien`
.`objektnummer`
, `Immobilien`
.`plz`
, `Immobilien`
.`strasse`
, `Immobilien`
.`ort`
, `Immobilien`
.`gesamtpreis`
, `Immobilien`
.`stichwort`
, `Immobilien`
.`mietekauf`
, `Immobilien`
.`iso_waehrung`
, `Immobilien`
.`nettokaltmiete`
, `Anhaenge`
.`objektnummer`
, `Anhaenge`
.`pfad`
, `Anhaenge`
.`gruppe`
, `Anhaenge`
.`anhangtitel` FROM `immobilien`
AS `Immobilien` LEFT
JOIN `anhaenge`
AS `Anhaenge` ON
(`Anhaenge`
.`objektnummer`
= `Immobilien`
.`objektnummer`
) WHERE `Immobilien`
.`plz` LIKE
"%" AND `Immobilien`
.`immobilienart`
= 1 GROUP BY `Immobilien`
.`objektnummer`
Und selbst wenn ich hier das GROUP BY unterlasse, erhalte ich keine unnötigen Einträge und belaste damit die Datenbank so wenig wie möglich. Wenn ich Zeit habe, werde ich mal die unterschiedlichen Rückantwortzeiten messen.
@Tobitobe: Danke, dass du mir das zutraust. Doch dazu fühle ich mich (noch) nicht berufen.
Ciao Thomas
