Zend Select с перезаписью полей самостоятельного присоединения

StackOverflow https://stackoverflow.com/questions/1164746

Вопрос

Посты и комментарии хранятся в одной таблице.Итак, чтобы получить каждое сообщение и комментарии к нему, мы делаем следующее:

    $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();

Проблема в том, что результирующий массив является плоским, а данные комментариев перезаписывают данные сообщения. Это пример того, что возвращается:

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

Нам хотелось бы, чтобы результат был примерно таким:

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

Любые намеки на другие решения также приветствуются.

Спасибо.

Это было полезно?

Решение

Если вы назовете все столбцы во втором соединении с сообщениями (например, idPost как child_idPost...и т. д.), вы получите множество строк, которые являются родительской строкой со столбцами второй строки.Это самое близкое, что вы получите.Затем вы можете получить родительские данные из первой строки, а затем просмотреть последующие строки, чтобы получить данные «один ко многим».

В противном случае просто выполните два запроса: один для родительского элемента, другой для дочерних элементов.В любом случае это может быть быстрее, чем создание такой большой таблицы результатов.

Другие советы

Zend не упрощает вашу предпочтительную форму, но это возможно.Однако обратите внимание, что вы просите сервер базы данных выполнить гораздо больше работы, чем вам на самом деле нужно, поскольку сообщение и информация о пользователе дублируются для каждого комментария.Джастин прав: второй запрос проще и, вероятно, быстрее.Тем не менее, я могу дать несколько советов по решению.

Для начала подумайте, что вы получите, используя Zend_Db::FETCH_NUM режим получения:

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

Тогда каким-то образом вам придется придумать сопоставление номеров столбцов с именами таблиц и столбцов:

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
)

Это та часть, где все становится сложнее, потому что табличная часть сильно специфична для интерфейса базы данных и не всегда возможна.Поскольку он привязан к набору результатов, адаптер также будет лучшим местом для его получения;это означает взлом классов Zend, возможно, путем предоставления вашего собственного класса адаптера.В зависимости от вашей базы данных информация может поступать из:

К сожалению, другие адаптеры могут не иметь возможности получить имя таблицы.

Да, у нас была такая же проблема, только что закончил писать об этом в блоге: http://www.kintek.com.au/blog/zend-db-and-joins/

Вам нужно назвать каждое поле уникальным образом, это известная ошибка в Zend: http://framework.zend.com/issues/browse/ZF-6421?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top