Yii2: Как выполнить группировку условий WHERE с использованием AND или OR?
Я новичок в фреймворке Yii-2. Как я могу выполнить следующий запрос в Yii-2, используя ActiveQuery и модели?
SELECT * FROM users AS u WHERE u.user_id IN(1,5,8) AND (u.status = 1 OR u.verified = 1) OR (u.social_account = 1 AND u.enable_social = 1)
Спасибо!
5 ответ(ов)
Вы можете попробовать следующее:
//SELECT * FROM users AS u WHERE u.user_id IN(1,5,8) AND (u.status = 1 OR u.verified = 1) OR (u.social_account = 1 AND u.enable_social = 1)
$model = arname()->find()
->andWhere(['user_id'=>[1,5,8]])
->andWhere(['or',
['status'=>1],
['verified'=>1]
])
->orWhere(['and',
['social_account'=>1],
['enable_social'=>1]
])
->all();
Эта конструкция выполняет запрос к базе данных, который получает пользователей с определёнными условиями. Первое условие — это ID пользователей, которые вы хотите выбрать, затем проверяются статус и верификация. Если статус или верификация равны 1, запись будет включена. Вдобавок, есть проверка на социальный аккаунт и его активность, которая также будет учитываться в результате запроса. Убедитесь, что ваши условия логически соответствуют тому, что вы хотите получить.
Я предполагаю, что вы уже знакомы с конфигурацией базы данных в Yii 2.0, которая в основном такая же, как и в версии Yii 1.0.
Если вы хотите использовать ActiveQuery, вам сначала нужно определить класс USERS
:
<?php
namespace app\models;
use yii\db\ActiveRecord;
class USERS extends ActiveRecord {
public static function tableName()
{
return 'users';
}
}
?>
Затем, когда вы будете его использовать, вы можете написать следующее:
<?
$usr_data = USERS::find()
->where("user_id IN(1,5,8) AND (status = 1 OR verified = 1) OR (social_account = 1 AND enable_social = 1)")
->all();
?>
На мой взгляд, ActiveQuery предоставляет возможность разделить SQL на подблоки. Однако не имеет смысла применять его, когда у вас такая сложная комбинация условий AND
и OR
.
Для того чтобы выполнить поиск пользователей с определёнными условиями в Yii2, вы можете использовать следующий код, который уже написан в вашем вопросе:
User::find()
->select('u_id, u_unique_id, u_first_name, u_last_name, u_username, u_email, u_image, u_phone')
->andWhere("u_status != 2 AND u_id != 1 AND u_role IN (6,7)")
->andWhere(
['or',
['like', 'u_first_name', $searchVal],
['like', 'u_last_name', $searchVal],
['like', 'u_username', $searchVal],
['like', 'u_email', $searchVal]
]
)
->all();
Этот код делает следующее:
- Запрашивает таблицу
User
, выбирая указанные поля (u_id
,u_unique_id
,u_first_name
,u_last_name
,u_username
,u_email
,u_image
,u_phone
). - Применяет условия фильтрации: статус пользователя не равен 2, идентификатор не равен 1, и роль пользователя должна быть либо 6, либо 7.
- Включает условия поиска по имени, фамилии, имени пользователя и email, используя оператор
LIKE
. Это позволяет находить пользователей, чьи данные содержат искомое значение$searchVal
. - В конце метод
all()
извлекает все записи, соответствующие условиям.
Убедитесь, что переменная $searchVal
правильно задаётся и экранируется для предотвращения SQL-инъекций. Если у вас возникнут дополнительные вопросы или требуется пояснение по какому-либо моменту, не стесняйтесь спрашивать!
Вы также можете сделать это следующим образом:
$data = model::find()
->andWhere('plz = :plz', [':plz' => 40])
->andWhere('plz = :plz', [':plz' => 40000])
->all();
Однако обратите внимание, что в данном примере используется один и тот же параметр :plz
для двух условий, что приведет к ошибке. Если вы хотите получить данные, соответствующие обоим условиям, вам стоит использовать оператор OR
или IN
, например:
$data = model::find()
->where(['plz' => [40, 40000]])
->all();
Таким образом, вы получите записи, соответствующие любому из перечисленных значений.
В вашем примере кода вы используете синтаксис MongoDB для построения запросов. Однако стоит отметить некоторые особенности, так как он может вызвать путаницу.
Ваш текущий код делает следующее:
- Он использует
andWhere
для фильтрации документов, у которыхstatus
равен 1 иactivity
находится в массиве[1, 2]
. - Затем, с помощью
orWhere
, он добавляет условие, чтобы найти документы, гдеyourField
входит в массивyourArray
.
Если вы хотите объединить оба условия корректно, вам нужно убедиться, что логика запроса соответствует вашим требованиям. В MongoDB правильный синтаксис может выглядеть чуть иначе.
Например, вы можете переписать ваш запрос следующим образом:
$query->orWhere([
'$or' => [
[
'$and' => [
['$eq' => ['status', 1]],
['$in' => ['activity', [1, 2]]],
]
],
['$in' => ['yourField', $yourArray]]
]
]);
Этот код будет правильно обрабатывать оба условия: он найдет документы, которые соответствуют первой группе условий (где status
равен 1 и activity
равно 1 или 2) или вторую группу условий (где yourField
входит в yourArray
).
Не забудьте протестировать запрос и убедиться, что он возвращает ожидаемые результаты. Если ваша работа похожа на операции с другими СУБД, вы правы, так как концептуально многие логические операции схожи, но синтаксис может различаться.
Какой лучший порядок сортировки использовать для MySQL с PHP? [закрыто]
SQL-инъекция, обхватывающая mysql_real_escape_string()
Ошибка при отправке пакета QUERY
Какой быстрее в PHP - MySQL или MySQLi?
MySQL: Удаление нескольких столбцов