Yii2 ActiveRecord: сложные вложения AND/OR

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
Ответить
GHopper
Сообщения: 83
Зарегистрирован: 2017.06.05, 10:53

Yii2 ActiveRecord: сложные вложения AND/OR

Сообщение GHopper »

Приветству.

Есть SQL-запрос к БД:

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

SELECT *
FROM "myCustomView" 
WHERE (
	(
		code = 'ATTR_GROUP' 
		AND (
			"value" = 'Мед' 
			OR "value" = 'Груша'
		)
	)
	OR (
		code = 'ATTR_SEX' 
		AND "value" = 'мужской'
		OR "value" = 'унисекс'
	)
)
Мне нужно получить аналог на AcriveRecord. На выходе имеем некоторый массив из которого нужно получить условия для будущего запроса:

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

[
    ['code' =>  'ATTR_SEX'],
    ['code' =>  'ATTR_GROUP],'
]
Этот массив с помощью не хитрого преобразования

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

$viewQuery->andFilterWhere(
    array_merge(['OR'], $theArray)
);
становится SQL-запросом

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

SELECT *
FROM "myCustomView" 
WHERE (
    code = 'ATTR_GROUP' 
    OR code = 'ATTR_SEX' 
)
Теперь я думаю как задать вложенные условие для value. К сожалению, моя фантазия заканчивается на идеи работать с текстом. Но, хотелось бы верить, что мы имеем "мощный инструмент с высокоуровневой абстракцией, который позволяет забыть про SQL". В общем, подкиньте идею как таке запросы формировать по умному. Входные данные - в любом виде, главное получить AR-объект, который возвращает требуемый запрос.
yan
Сообщения: 942
Зарегистрирован: 2011.03.23, 09:28
Откуда: Уфа

Re: Yii2 ActiveRecord: сложные вложения AND/OR

Сообщение yan »

https://www.yiiframework.com/doc/guide/ ... tor-format
and: операнды должны быть объединены с помощью оператора AND. Например, ['and', 'id=1', 'id=2'] сгенерирует id=1 AND id=2. Если операнд массив, он будет сконвертирован в строку по правилам описанным ниже. Например, ['and', 'type=1', ['or', 'id=1', 'id=2']] сгенерирует type=1 AND (id=1 OR id=2). Этот метод не производит никакого экранирования.

or: похож на оператор and за исключением того, что будет использоваться оператор OR.
GHopper
Сообщения: 83
Зарегистрирован: 2017.06.05, 10:53

Re: Yii2 ActiveRecord: сложные вложения AND/OR

Сообщение GHopper »

Спасибо, получилось. В конце цикла вызываю

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

andFilterWhere(['AND', "code='{$code}'", array_merge(['OR'], $cond)]);
и передаю $cond, которую предварительно заполняю найденными условиями. Строится все как и задумывалось!
GHopper
Сообщения: 83
Зарегистрирован: 2017.06.05, 10:53

Re: Yii2 ActiveRecord: сложные вложения AND/OR

Сообщение GHopper »

Поторопился...

Между двумя условиями с code=... получается AND, а нужен OR.
Вот первая часть:

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

andFilterWhere(
    [
        'AND',
        "code='ATTR_GROUP'",
        ['OR', ['value' => 'Мед'],['value' => 'Груша']]
    ]
);
Как добавить вторую часть с code='ATTR_SEX' но через оператор OR?
mader
Сообщения: 84
Зарегистрирован: 2015.06.15, 13:44
Откуда: Воронеж

Re: Yii2 ActiveRecord: сложные вложения AND/OR

Сообщение mader »

попробуйте как-то так. должно быть типа такого что-то.

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

where(
	[
        	'AND',
        	"code='ATTR_GROUP'",
        	['OR', ['value' => 'Мед'],['value' => 'Груша']]
       ]
)->orWhere (
	 [
        	'AND',
        	"code='ATTR_GROUP'",
        	['OR', ['value' => 'Мед'],['value' => 'Груша']]
        ]
)
GHopper
Сообщения: 83
Зарегистрирован: 2017.06.05, 10:53

Re: Yii2 ActiveRecord: сложные вложения AND/OR

Сообщение GHopper »

А как их объеденить в скобки, чтобы можно было по другим критериям еще искать?

Конструкция вида

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

where(
	[
        	'AND',
        	"code='ATTR_SEX'",
        	['OR', ['value' => 'М'],['value' => 'Ж']]
       ]
)->orWhere (
	 [
        	'AND',
        	"code='ATTR_GROUP'",
        	['OR', ['value' => 'Мед'],['value' => 'Груша']]
        ]
)
жизнеспособна, но эти условия нужно взять в скобри и объеденить с другими (например 1=1).
Т.е. итоговый запрос:

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

SELECT *
FROM "myCustomView" 
WHERE 
1=1 
AND (
	(
		code = 'ATTR_GROUP' 
		AND (
			"value" = 'Мед' 
			OR "value" = 'Груша'
		)
	)
	OR (
		code = 'ATTR_SEX' 
		AND "value" = 'мужской'
		OR "value" = 'унисекс'
	)
)
yan
Сообщения: 942
Зарегистрирован: 2011.03.23, 09:28
Откуда: Уфа

Re: Yii2 ActiveRecord: сложные вложения AND/OR

Сообщение yan »

GHopper писал(а): 2018.07.26, 22:47 Поторопился...

Между двумя условиями с code=... получается AND, а нужен OR.
можно просто еще уровень вложенности добавить
GHopper
Сообщения: 83
Зарегистрирован: 2017.06.05, 10:53

Re: Yii2 ActiveRecord: сложные вложения AND/OR

Сообщение GHopper »

yan писал(а): 2018.07.26, 23:29
GHopper писал(а): 2018.07.26, 22:47 Поторопился...

Между двумя условиями с code=... получается AND, а нужен OR.
можно просто еще уровень вложенности добавить
Было бы не плохо, но я не совсем понимаю о чем речь. Моих знаний пока еще слишком мало, поэтому было бы идеально увидеть живой пример.
Куда здесь добавить этот присловутый "уровень вложенности"?

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

andFilterWhere(
    [
        'AND',
        "code='ATTR_GROUP'",
        ['OR', ['value' => 'Мед'],['value' => 'Груша']]
    ]
);
andFilterWhere(
    [
        'AND',
        "code='ATTR_SEX'",
        ['OR', ['value' => 'Ж'],['value' => 'М']]
    ]
);
yan
Сообщения: 942
Зарегистрирован: 2011.03.23, 09:28
Откуда: Уфа

Re: Yii2 ActiveRecord: сложные вложения AND/OR

Сообщение yan »

GHopper писал(а): 2018.07.26, 23:37
Было бы не плохо, но я не совсем понимаю о чем речь. Моих знаний пока еще слишком мало, поэтому было бы идеально увидеть живой пример.
Куда здесь добавить этот присловутый "уровень вложенности"?

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

['OR',// 1 level
  ['name0' => 0], 
  ['AND', // 2 level
     ['name1' => 11], 
     ['OR', // 3 level
       ['name2' => 22],
       ['name3' => 33]
    ]
  ]
]
GHopper
Сообщения: 83
Зарегистрирован: 2017.06.05, 10:53

Re: Yii2 ActiveRecord: сложные вложения AND/OR

Сообщение GHopper »

Кажется я начинаю понимать ) В итоге пришел к такому исходному массиву условий:

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

andWhere(
    [
        'OR',
        [
            'AND',
            ['code' => 'ATTR_SEX'],
            [
                'OR',
                ['value' => '1'],
                ['value' => '2']
            ]
        ],
        [
            'AND',
            ['code' => 'ATTR_GROUP'],
            [
                'OR',
                ['value' => '3'],
                ['value' => '4']
            ]
        ],
    ]
);
Еще не тестировал, но логику работы конструктора понял и уверен что разберусь.

Всем спасибо, особенно Yan )
Ответить