У меня есть запрос, в котором я хочу узнать название компании и количество ее сотрудников. Дело в том, что я хочу отфильтровать этот результат по некоторым условиям (например, employee_number > 50
и т. д.). Моя проблема в том, что при построении запроса я не знаю, как отфильтровать этот результат, так как условие задается над вычисляемым полем, поэтому при применении условия оно дает мне следующее
Error: `SQLSTATE[42S22]: Column not found: 1054 Unknown column 'employee_number' in 'where clause'`.
Я пробовал разные вещи, но это то, что у меня сейчас есть:
$query = $this->Companies->find('all')->where($conditions)->contain(['Users']);
$query
->select(['Users.name',
'Company.modified',
'employee_number' => $query->func()->count('DISTINCT(Employees.id)')])
->where('employee_number >' => 50 )
->leftJoinWith('Employees', function (\Cake\ORM\Query $query) {
return $query->where(['deleted' => 0]);
})
->group(['Employees.company_id', 'Company.id']);
Во-первых, вы не можете ссылаться на агрегат в предложении WHERE
, так как группировка происходит позже, поэтому возникает ошибка, поле employee_number
не существует, когда применяются условия WHERE
, вместо этого вы должны использовать предложение HAVING
.
В зависимости от используемой СУБД вы можете ссылаться на столбец из списка выбора, например, MySQL позволяет это:
$query
->select([
'Users.name',
'Company.modified',
'employee_number' => $query->func()->count('DISTINCT Employees.id')
])
->leftJoinWith('Employees', function (\Cake\ORM\Query $query) {
return $query->where(['deleted' => 0]);
})
->group(['Employees.company_id', 'Company.id'])
->having(['employee_number >' => 50]);
в то время как Postgres, например, этого не делает и требует, чтобы вы повторили агрегацию внутри предложения HAVING
:
->having(function (
\Cake\Database\Expression\QueryExpression $exp,
\Cake\ORM\Query $query
) {
return $exp->gt($query->func()->count('DISTINCT Employees.id'), 50);
});
пс. использование DISTINCT
должно быть необходимо только тогда, когда у вас есть, например, несколько соединений, которые приведут к дублированию соединенных строк.
Смотрите также
Спасибо за это, я смог отфильтровать, используя свое вычисляемое поле, добавив предложение having
Спасибо за ваш ответ! В этом случае мне было нужно предложение have.