Небольшая заметка, которая может ответить не только на проблему, обозначенную в заголовке, но и продемонстрировать 3 способа построения запроса и получения результатов запросов. К сожалению, стандартно подставив команду OrderBy перед GroupBy в MySQL вы получите совсем не то что ожидаете, а происходит это потому, что выполняется сначала группировка данных, а уже затем они сортируются, но уже в результирующем наборе нет нужных нам данных, решается эта проблема в «подсовывании» новой таблицы уже с правильной для нас сортировкой, запросом это выглядит примерно так:
SELECT * FROM ( SELECT * FROM `table` ORDER BY `date` DESC ) as `new_table` GROUP BY `test_id`
В результате выполнения данного запроса мы получим сгруппированные данные по test_id новой таблицы new_table в которой мы отсортировали данные по дате. Теперь как то же самое сделать использую Yii2? Я опишу 3 возможных способа:
Выполнение sql запроса в Yii2
Думаю здесь все достаточно просто: скидываем текст запроса в переменную и выполняем команду через базовый объект:
$sql = 'SELECT * FROM ( SELECT * FROM `table` ORDER BY `date` DESC ) as `new_table` GROUP BY `test_id` '; $result = Yii::$app->db->createCommand($sql)->queryAll();
На выходе в переменной $result получаем массив с результатами запроса
Использование конструктора запросов
Более интересным методом получения данных в нашей ситуации является использование конструктора запросов:
$result = (new Query()) ->from([ 'new_table' => (new Query()) ->from('table') ->orderBy([ 'date' => SORT_DESC ]) ]) ->groupBy('test_id') ->all();
Код получился компактнее и читаемее, не правда ли? Из интересного в данном куске кода пожалуй объявление двух объектов Query() и использование базовой константы SORT_DESC, а в переменной $result окажется все тот же массив данных.
Кстати, чтобы все заработало в контроллере должно быть указано:
use yii\db\Query;
Использование базовой модели
Самым верным вариантом получения результатов при решении данной задачи является использование ранее сгенерированной модели:
$result = Table::find() ->from([ 'new_table' => Table::find() ->orderBy([ 'date' => SORT_DESC ]) ]) ->groupBy('test_id') ->all()
После выполнения в переменной $result будет…, верно модель данных, чтобы был массив нужно использовать asArray(), о котором немного подробнее было рассказано тут. Плюс использование модели и Active Record для построения запроса это возможность подставить в запрос что-то вроде:
->with('test')
и получить кроме всего прочего соединенные данные из таблицы test.
Ах да, в контроллере должно быть:
use app\models\Table;comments powered by HyperComments