2009-07-22 9 views
0

Beiträge und Kommentare werden in derselben Tabelle gespeichert. So bekommt jeden Beitrag und seine Kommentare, die wir dies tun:Zend Select mit Self-Join-Überschreibungsfeldern

$posts = $this->select()->setIntegrityCheck(false) 
         ->from(array('post' => 'Posts'), array('*')) 
         ->where('post.idGroup = ' . $idGroup) 
         ->where('post.idTopic IS NULL') 
         ->order('post.date DESC') 
         ->limit($resultsPerPage, $resultsPerPage * ($page - 1)) 
         ->joinLeft(array('user' => 'Users'), 'post.idUser = user.idUser', 
          array('idUser', 'fname', 'lname', 'profileUrl', 'photoUrl')) 
         ->joinLeft(array('comment' => 'Posts'), 'comment.idTopic = post.idPost') 
         ->query()->fetchAll(); 

Das Problem ist, dass die resultierende Anordnung ist flach und die Kommentardaten überschreiben die Post-Daten, ist dies ein Beispiel dafür, was zurückgegeben wird:

[1] => Array 
    (
     [idPost] => 13 
     [idTopic] => 11 
     [idGroup] => 1 
     [idUser] => 84 
     [postContent] => Hello my name is Mud. 
     [postUrl] => 13/hello-my-name-is-mud 
     [postVotes] => 
     [postScore] => 
     [date] => 2009-07-21 16:39:09 
     [fname] => John 
     [lname] => Doe 
     [profileUrl] => john-doe 
     [photoUrl] => uploads/userprofiles/0/84/pic84_14 
    ) 

Was würden wir mit dem Ergebnis zufrieden zu sein, ist etwas mehr wie folgt aus:

[1] => array(
      [post] => array(
       [0] => array(
        idPost => 12, 
        postContent => This is a post..., 
        idGroup => 1 
        ... 
       ) 
      ), 
      [user] => array(
       [0] => array(
        userName => JohnDoe 
        ... 
        ) 
       ), 
      [comments] => array(
       [0] => array(
        idPost => 15, 
        postContent => This is a comment..., 
        idGroup => 1 
        ... 
       ), 
       [1] => array(
        idPost => 17, 
        postContent => This is another comment..., 
        idGroup => 1 
        ... 
       ) 
      ) 
     ) 

Irgendwelche Hinweise zu anderen Lösungen ist auch sehr willkommen.

Danke.

+1

SQL nicht wie das funktionieren. Sie müssen eine Reihe von Abfragen durchführen, um die Daten in diesem Format abzurufen. – jason

Antwort

1

Wenn Sie alle Spalten im zweiten Join mit Posts verknüpfen (wie idPost als child_idPost ... usw.), erhalten Sie viele Zeilen, die die übergeordnete Zeile mit den Spalten der zweiten Zeile darstellen. Das ist ungefähr der nächste, den du bekommst. Sie können dann die übergeordneten Daten aus der ersten Zeile abrufen und dann die nachfolgenden Zeilen durchlaufen, um Ihre 1: n-Daten zu erhalten.

Ansonsten tun Sie einfach zwei Abfragen, eine für die Eltern, eine für die Kinder. Es kann schneller sein, als diese große Ergebnistabelle trotzdem zu erstellen.

+0

Yeah-Aliasing scheint die einzige Lösung zu sein, um die Überlappung zu verhindern. Was wir damit erreicht haben, ist eine Schleife, die eine weitere Abfrage macht, um die Kommentare zu jedem Beitrag zu erhalten.Also eine Seite mit 10 Posts ist 11 Anfragen oder mehr, es fühlt sich so falsch an. – lasse

+0

Dies könnte auf 2 Abfragen reduziert werden, indem alle Post-IDs aus der ersten Abfrage in eine "IN (...)" -Klausel der zweiten Abfrage gesammelt werden. Das macht die Assoziation von Kindern mit Eltern etwas schwieriger, aber möglich. – eswald

0

Zend macht Ihre bevorzugte Form nicht einfach, aber es könnte möglich sein. Beachten Sie jedoch, dass Sie den Datenbankserver bitten, wesentlich mehr Arbeit zu erledigen, als Sie tatsächlich möchten, da die Post- und Benutzerinformationen für jeden Kommentar dupliziert werden. Justin ist richtig, dass eine zweite Abfrage einfacher und wahrscheinlich schneller ist. Ich kann jedoch einige Hinweise auf eine Lösung geben.

beginnen zu betrachten, was Sie mithilfe der Zend_Db::FETCH_NUM Fetch-Modus erhalten würde:

Array(
    [0] => Array(
     [0] => 12 
     [1] => 
     [2] => 1 
     [3] => 84 
     [4] => This is a post..., 
     [5] => 12/this-is-a-post 
     [6] => 
     [7] => 
     [8] => 2009-07-21 16:39:09 
     [9] => 84 
     [10] => John 
     [11] => Doe 
     [12] => john-doe 
     [13] => uploads/userprofiles/0/84/pic84_14 
     [14] => 15 
     [15] => 12 
     [16] => 1 
     [17] => 79 
     [18] => This is a comment..., 
     [19] => 
     [20] => 
     [21] => 
     [22] => 2009-07-21 17:40:10 
    ), 
    [1] => Array(
     [0] => 12 
     [1] => 
     [2] => 1 
     [3] => 84 
     [4] => This is a post..., 
     [5] => 12/this-is-a-post 
     [6] => 
     [7] => 
     [8] => 2009-07-21 16:39:09 
     [9] => 84 
     [10] => John 
     [11] => Doe 
     [12] => john-doe 
     [13] => uploads/userprofiles/0/84/pic84_14 
     [14] => 17 
     [15] => 12 
     [16] => 1 
     [17] => 127 
     [18] => This is another comment..., 
     [19] => 
     [20] => 
     [21] => 
     [22] => 2009-07-20 10:31:26 
    ) 
) 

Dann irgendwie müssen Sie kommen mit der Abbildung von Spaltennummern zu Tabellen- und Spaltennamen:

Array(
    [0] => post.idPost 
    [1] => post.idTopic 
    [2] => post.idGroup 
    [3] => post.idUser 
    [4] => post.postContent 
    [5] => post.postUrl 
    [6] => post.postVotes 
    [7] => post.postScore 
    [8] => post.date 
    [9] => user.idUser 
    [10] => user.fname 
    [11] => user.lname 
    [12] => user.profileUrl 
    [13] => user.photoUrl 
    [14] => comment.idPost 
    [15] => comment.idTopic 
    [16] => comment.idGroup 
    [17] => comment.idUser 
    [18] => comment.postContent 
    [19] => comment.postUrl 
    [20] => comment.postVotes 
    [21] => comment.postScore 
    [22] => comment.date 
) 

Dies ist der Teil, wo es schwierig wird, weil die Tabelle Teil davon stark spezifisch für die Datenbankschnittstelle ist, und nicht immer möglich. Da er an die Ergebnismenge gebunden ist, ist der Adapter auch der beste Ort, um ihn zu erhalten. das heißt, Zend-Klassen zu hacken, möglicherweise durch Bereitstellung einer eigenen Adapterklasse. Je nach Ihrer Datenbank können die Informationen stammen aus:

Andere Adapter könnten einen Weg nicht haben die Tabellennamen zu erhalten, leider.