ActiveRecord

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
Ответить
Tivos
Сообщения: 41
Зарегистрирован: 2015.08.12, 12:34

ActiveRecord

Сообщение Tivos »

Здравствуйте! Не могу написать правильно запрос в БД.
Помогите разобраться, как правильно сделать запрос.
Изображение
Мне нужно получить все товары в которых attributes.value = 32 and attributes.value = 'black'.
В данном примере это NIKE

Аватара пользователя
Dominus
Сообщения: 874
Зарегистрирован: 2013.03.14, 21:27
Откуда: Россия, Иваново
Контактная информация:

Re: ActiveRecord

Сообщение Dominus »

Если без связи в модели ModelGoods:

Код: Выделить всё

$result = ModelAttributes::find()->where(['good_id' => 2])->andWhere(['value' => ['32', 'black']])->all();
Если есть связь в модели ModelGoods, что правильнее, то:

Код: Выделить всё

$model = ModelGoods::findOne(2);
$result = $model->getRelationsAttributes()->where(['value' => ['32', 'black']])->all();
где getRelationsAttributes() название связи hasMany с моделью ModelAttributes в модели ModelGoods.

http://www.yiiframework.com/doc-2.0/yii ... ecord.html
http://www.yiiframework.com/doc-2.0/gui ... ecord.html
Не спорь с дураком, иначе окружающие не правильно поймут кто из вас дурак!

caHek2x
Сообщения: 1226
Зарегистрирован: 2016.04.12, 20:41

Re: ActiveRecord

Сообщение caHek2x »

Dominus писал(а):
2017.12.12, 16:00

Код: Выделить всё

$result = ModelAttributes::find()->where(['good_id' => 2])->andWhere(['value' => ['32', 'black']])->all();
не ... ему надо AND ...
тут надо бы еще добавить group by и having count =2

и where(['good_id' => 2]) ему не надо ... т.к. ему надо найти этот good_id запросом выше ...

Аватара пользователя
Dominus
Сообщения: 874
Зарегистрирован: 2013.03.14, 21:27
Откуда: Россия, Иваново
Контактная информация:

Re: ActiveRecord

Сообщение Dominus »

А, наоборот, ну тогда можно так:

Код: Выделить всё

$attributes = ModelAttributes::find()->where(['value' => ['32', 'black']])->all();
$goods = [];
foreach($attributes as $attribute) {
	$goods[] = ModelGoods::findOne($attribute->good_id);
}
var_dump($goods);
Не спорь с дураком, иначе окружающие не правильно поймут кто из вас дурак!

caHek2x
Сообщения: 1226
Зарегистрирован: 2016.04.12, 20:41

Re: ActiveRecord

Сообщение caHek2x »

и так тоже не прокатит ... так достанет все 32 и все черные ... а автору поста надо 32 AND черные )
да и вообще это странный код
ведь можно вместо all column и потом достать сразу все ModelGoods а не по одной ...

Аватара пользователя
Dominus
Сообщения: 874
Зарегистрирован: 2013.03.14, 21:27
Откуда: Россия, Иваново
Контактная информация:

Re: ActiveRecord

Сообщение Dominus »

Что то я вообще не въезжаю что нужно :D
Не спорь с дураком, иначе окружающие не правильно поймут кто из вас дурак!

caHek2x
Сообщения: 1226
Зарегистрирован: 2016.04.12, 20:41

Re: ActiveRecord

Сообщение caHek2x »

запрос: дайте мне 32 размер черного цвета
а ваш запрос возвратит весь товар 32го размера (любого цвета) и весь товар черного цвета (любого размера) :-)

Tivos
Сообщения: 41
Зарегистрирован: 2015.08.12, 12:34

Re: ActiveRecord

Сообщение Tivos »

Всем спасибо.
От так работает

Код: Выделить всё

 Goods::find()
	->from(Goods::tableName() . ' AS g')
	->innerJoin(['a_32' => Attributes::find()->select('good_id')->where(['value' => 32])], 'g.id = a_32.good_id')
	->innerJoin(['a_black' => Attributes::find()->select('good_id')->where(['value' => 'black'])], 'g.id = a_black.good_id')
	->all()
	

caHek2x
Сообщения: 1226
Зарегистрирован: 2016.04.12, 20:41

Re: ActiveRecord

Сообщение caHek2x »

идеи для размышления ... можно еще такими вариантами решить:

Код: Выделить всё

// это вариант через запросы, каждый отсеивающий то goods в которых нет нужного аттрибута
$values = ['32', 'черные'];
$goods_id=null;
foreach($values as $value)
{
	$query = Attributes::find()->select('good_id')->where(['value'=>$value]);
	if ($goods_id!==null){
		if (count($goods_id)==0) break;
		$query->andWhere(['good_id'=>$goods_id]);
	}
	$goods_id = $query->column();
}
$goods = ($goods_id!==null && count($goods_id)>0)?Goods::find()->where(['id'=>$goods_id])->all():[];


//а это вариант с группировкой...
$values = ['32', 'черные'];
$goods_id = Attributes::find()
	->select('good_id')
	->where(['value'=>$values])
	->groupBy("good_id")
	->having(new Expression("count(*)=".count($values)))
	->column();
$goods = (count($goods_id)>0)?Goods::find()->where(['id'=>$goods_id])->all():[];
смотрите что быстрее будет работать ...

Ответить