Страница 1 из 1

ActiveDataProvider joinWith и OrderBy

Добавлено: 2019.04.16, 19:59
webplus
Здравствуйте!

Код: Выделить всё

        $query = Dialog::find();
        $query->joinWith(['messageLast']);

        $dataProvider = new ActiveDataProvider([
            'query' => $query,
            'pagination' => [
                'pageSize' => 20,
            ],
            'sort'=> [
                'attributes' => [
                    'user1',
                    'user2',
                    'theme',
                    'updated_at',
                    'messages.date_add'
                ],
                'defaultOrder' => [
                    'messages.date_add' => SORT_DESC,
                ]
            ],
        ]);
в модели

Код: Выделить всё

    public function getMessageLast(){
        return $this->hasOne(Message::className(), ['dialog_id' => 'id'])->orderBy('date_add DESC');
    }
Выводит в грид не 20 записей, а по 14 (на каждой странице разное количество записей).
Пробовал добавлять ->distinct() тогда выводит 20 записей как надо, но не сортирует по полю 'messages.date_add' => SORT_DESC , такая же ситуация с group by.

А если сам sql запрос ввести в консоль, то выводит как надо 20 записей с сортировкой. Наверно что то с ActiveDataProvider

Re: ActiveDataProvider joinWith и OrderBy

Добавлено: 2019.04.16, 20:11
futbolim
$query->with(['messageLast']);
with делает аналог left join (только отдельным запросом)
joinWith делает inner join по идее

Re: ActiveDataProvider joinWith и OrderBy

Добавлено: 2019.04.16, 20:30
webplus
futbolim писал(а): 2019.04.16, 20:11 $query->with(['messageLast']);
with делает аналог left join (только отдельным запросом)
joinWith делает inner join по идее
попробовал

Код: Выделить всё

        $query->innerJoinWith(['messageLast']);
но выводит в место 20 записей - 14 и сортирует как надо. Если добавить ->distinct() то 20 выводит как надо, но сортировка слетает.

Re: ActiveDataProvider joinWith и OrderBy

Добавлено: 2019.04.16, 20:32
futbolim
Покажите тот sql запрос, который 14 выбирает

Re: ActiveDataProvider joinWith и OrderBy

Добавлено: 2019.04.16, 20:36
webplus
futbolim писал(а): 2019.04.16, 20:32 Покажите тот sql запрос, который 14 выбирает

Код: Выделить всё

SELECT `dialogs`.* FROM `dialogs` INNER JOIN `messages` ON `dialogs`.`id` = `messages`.`dialog_id` ORDER BY `messages`.`date_add` DESC LIMIT 20
если его в консоль phpmyadmin-а ввести, то выводит как надо 20 записей и сортирует. А в ActiveDataProvider отдает только 14 записей

Re: ActiveDataProvider joinWith и OrderBy

Добавлено: 2019.04.16, 21:06
webplus
futbolim писал(а): 2019.04.16, 20:32 Покажите тот sql запрос, который 14 выбирает
Ссори в консоли phpmyadmin запрос:

Код: Выделить всё

SELECT `dialogs`.* FROM `dialogs` INNER JOIN `messages` ON `dialogs`.`id` = `messages`.`dialog_id` ORDER BY `messages`.`date_add` DESC LIMIT 20
выдает 20 записей но с дублями, т.е. ID записи я заметил повторяются. если добавить GROUP BY `messages`.`dialog_id` к запросу то группирует
и выводит как надо 20 записей без дублей, но сортировка ORDER BY `messages`.`date_add` DESC не работает, сортирует по первому `messages`.`date_add` , а должно по последнему так как у нас DESC

вот запрос с гроуп:

Код: Выделить всё

SELECT `dialogs`.*, `messages`.`date_add` AS `m_date_add` FROM `dialogs` INNER JOIN `messages` ON `dialogs`.`id` = `messages`.`dialog_id` GROUP BY `messages`.`dialog_id` ORDER BY `m_date_add` DESC LIMIT 20

Re: ActiveDataProvider joinWith и OrderBy

Добавлено: 2019.04.17, 00:48
futbolim
Ну а второй нормально сортирует?

Re: ActiveDataProvider joinWith и OrderBy

Добавлено: 2019.04.17, 10:33
Loveorigami
Это датапровайдер при подготовке моделей записывает их в массив. Ключ массива - это id первичной модели.
выдает 20 записей но с дублями, т.е. ID записи я заметил повторяются.
Если у вас несколько строк с одинаковым id - они и перезаписываются в массиве датапровайдера.

Как такое получилось у вас - это вопрос архитектуры.

Иначе - чтоб вывести Все записи, вам в запрос надо добавить ->indexBy('...') с уникальным ключом, который Вы можете вытянуть запросом.

Re: ActiveDataProvider joinWith и OrderBy

Добавлено: 2019.04.17, 12:37
webplus
futbolim писал(а): 2019.04.17, 00:48 Ну а второй нормально сортирует?
в версии mysql 5.7 есть странность работы с group by и order by. Об этом пишут в интернете. Пишут что mysql не дает гарантии вывода результатов при использовании group by и order by
в ранних версиях mysql тот запрос что я выше привел работает нормально, но а в этой версии отработал запрос с MAX(messages.date_add) as m_date_add в селекте
вот сам запрос:

Код: Выделить всё

SELECT `dialogs`.*, MAX(messages.date_add) as m_date_add FROM `dialogs` LEFT JOIN `messages` ON `dialogs`.`id` = `messages`.`dialog_id` GROUP BY `messages`.`dialog_id` ORDER BY `m_date_add` DESC LIMIT 20
я сделал MAX(messages.date_add) as m_date_add а потом по нему сортировку. И все работает корректно!

Re: ActiveDataProvider joinWith и OrderBy

Добавлено: 2019.04.17, 13:13
someweb
Это не странность MySql, при использовании GROUP BY в списке выбора должны присутствовать только поля перечисленные в GROUP BY или агрегатные функции.