Frage

Beiträge und Kommentare werden in derselben Tabelle gespeichert.Um jeden Beitrag und seine Kommentare zu erhalten, gehen wir folgendermaßen vor:

    $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 besteht darin, dass das resultierende Array flach ist und die Kommentardaten die Beitragsdaten überschreiben. Dies ist 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
    )

Wir möchten, dass das Ergebnis etwa so aussieht:

    [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
                    ...
                )
            )
        )

Hinweise zu anderen Lösungen sind ebenfalls sehr willkommen.

Danke.

War es hilfreich?

Lösung

Wenn Sie alle Spalten im zweiten Join mit Posts aliasen (z. B. idPost als child_idPost ...)usw.), erhalten Sie viele Zeilen, die die übergeordnete Zeile mit den Spalten der zweiten Zeile bilden.Das ist ungefähr das Beste, was Sie erreichen werden.Anschließend können Sie die übergeordneten Daten aus der ersten Zeile abrufen und dann die nachfolgenden Zeilen durchlaufen, um Ihre Eins-zu-viele-Daten zu erhalten.

Andernfalls führen Sie einfach zwei Abfragen durch, eine für das übergeordnete Element und eine für die untergeordneten Elemente.Es kann ohnehin schneller sein, als diese große Ergebnistabelle zu erstellen.

Andere Tipps

Zend macht Ihre bevorzugte Form nicht einfach, aber es könnte möglich sein.Beachten Sie jedoch, dass Sie dem Datenbankserver weitaus mehr Arbeit abverlangen, als Sie tatsächlich möchten, da die Beitrags- und Benutzerinformationen für jeden Kommentar dupliziert werden.Justin hat Recht, dass eine zweite Abfrage einfacher und wahrscheinlich schneller ist.Ich kann jedoch einige Hinweise zur Lösung geben.

Überlegen Sie zunächst, was Sie durch die Verwendung erreichen würden Zend_Db::FETCH_NUM Abrufmodus:

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 muss man sich irgendwie die Zuordnung von Spaltennummern zu Tabellen- und Spaltennamen einfallen lassen:

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, in dem es schwierig wird, da der Tabellenteil stark spezifisch für die Datenbankschnittstelle ist und nicht immer möglich ist.Da es an die Ergebnismenge gebunden ist, ist der Adapter auch der beste Ort, um es zu erhalten.Das bedeutet, Zend-Klassen zu hacken, möglicherweise durch die Bereitstellung einer eigenen Adapterklasse.Abhängig von Ihrer Datenbank können die Informationen stammen aus:

Andere Adapter haben möglicherweise leider keine Möglichkeit, den Tabellennamen abzurufen.

Ja, wir hatten das gleiche Problem und sind gerade mit dem Bloggen darüber fertig geworden: http://www.kintek.com.au/blog/zend-db-and-joins/

Sie müssen jedes Feld eindeutig benennen. Dies ist ein bekannter Fehler in Zend: http://framework.zend.com/issues/browse/ZF-6421?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top