@belyaevcyrill

Как написать такой SQL-запрос в виде ActiveRecord?

Есть такой SQL-запрос:
update users u_
join (
    select m.user_id id, u.name name, SUM(IF(m.`status` = 'new' or m.`status` = 'newest', 1, 0)) new_marks_total
    from marks m
    left join users u on u.id = m.user_id
    where m.`status` in ('oldest', 'old', 'new', 'newest') and m.user_id is not null and u.name is not null
    group by m.user_id
) t1 on t1.id = u_.id
set u_.marks_total = t1.new_marks_total
where u_.id = <USER_ID>;


Его суть в том, что по ИДу пользователя подсчитываем количество всех оценок со статусами new и newest в таблице marks и добавляем в поле marks_total в таблице пользователя.

Как такой SQL сделать в YII2 не с помощью createCommand(), а с помощью ActiveRecord?
  • Вопрос задан
  • 272 просмотра
Решения вопроса 1
@vism
Зачем это писать на AR?
Вы после апдейта модель юзера хотите получить?
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@BorisKorobkov Куратор тега MySQL
Web developer
1. Полностью на ActiveRecord не получится, ибо он только для ANSI SQL, а ваш update двух таблиц будет работать только в MySQL.
Можно частично:
echo Mark::find()
->select(['user_id', 'name', 'new_marks_total' => new Expression('...')])
->with('user')
->where(['status' => ['oldest', 'old', 'new', 'newest']])
->andWhere(['IS NOT', 'user_id', null])
->andWhere(['IS NOT', 'name', null])
->groupBy('user_id')
->createCommand()
->rawSQL;


2. Но это все равно говнокод. Потому что при group by можно в select только это группируемое поле или групповые функции. Например, есть user с двумя mark. При группировке по user.id какая из двух mark должна быть в m.status?
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы