Сортировка с конкретными элементами в начале
Предположим, у нас есть таблица order со следующими полями:
CREATE TABLE `order` (`id` int(11) NOT NULL AUTO_INCREMENT,
`order_status` enum('новый','ожидает оплаты','гарантия','архив','заморожен','удален'),
`created_at` int(10) unsigned NOT NULL,
`client_id` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`))
И необходимо составить такой sql-запрос, чтобы можно было получить список заказов в таком порядке:
- В начале показать заказы со статусом "ожидает оплаты"
- Потом показать заказы со статусом "гарантия"
- Затем показать заказы с остальными статусами
Решать поставленную задачу будем следующим образом:
сформируем запрос на получением всех заказов:
Order::find()->all();
Теперь добавим сортировку по полю "статус заказа":
Order::find()->orderBy("`order_status` DESC")->all();
Попробуем для начала получить все заказы, но только сначала покажем те заказы, которые находятся в статусе "ожидает оплаты", а ниже остальные заказы. Как же сделать это обычным sql-запросом? А очень просто! Ниже пример, как можно реализовать произвольную сортировку в sql-запросе:
SELECT * FROM `order` ORDER BY `order_status`='ожидает оплаты' DESC
Добавим к нашему SQL-запросу сортировку по нескольким полям (в нашем случае - по второму искомому значению поля "статус заказа"):
SELECT * FROM `order` ORDER BY `order_status`='ожидает оплаты' DESC, `order_status`='гарантия' DESC
И добавим сортировку по убыванию для оставшихся статусов заказа:
SELECT * FROM `order` ORDER BY `order_status`='ожидает оплаты' DESC, `order_status`='гарантия' DESC, `order_status` DESC
Чтобы такой запрос реализовать в Yii2, мы просто перенесем сортировку по нескольким полям:
Order::find()->orderBy("`order_status`='ожидает оплаты' DESC, `order_status`='гарантия' DESC, `order_status` DESC")->all();
В итоге получим нужный результат!