Страница 1 из 1

ActiveRecord

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

Re: ActiveRecord

Добавлено: 2017.12.12, 16:00
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

Re: ActiveRecord

Добавлено: 2017.12.12, 16:23
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 запросом выше ...

Re: ActiveRecord

Добавлено: 2017.12.12, 16:40
Dominus
А, наоборот, ну тогда можно так:

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

$attributes = ModelAttributes::find()->where(['value' => ['32', 'black']])->all();
$goods = [];
foreach($attributes as $attribute) {
	$goods[] = ModelGoods::findOne($attribute->good_id);
}
var_dump($goods);

Re: ActiveRecord

Добавлено: 2017.12.12, 16:43
caHek2x
и так тоже не прокатит ... так достанет все 32 и все черные ... а автору поста надо 32 AND черные )
да и вообще это странный код
ведь можно вместо all column и потом достать сразу все ModelGoods а не по одной ...

Re: ActiveRecord

Добавлено: 2017.12.12, 16:49
Dominus
Что то я вообще не въезжаю что нужно :D

Re: ActiveRecord

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

Re: ActiveRecord

Добавлено: 2017.12.12, 16:58
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()
	

Re: ActiveRecord

Добавлено: 2017.12.12, 17:04
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():[];
смотрите что быстрее будет работать ...