Выборка с одновременным выполнением двух условий ИЛИ — различия между версиями

Материал из Umicms
Перейти к:навигация, поиск
(Новая страница: «'''Актуально для версии 2.9.6''' == Задача == Предположим у товаров по группам заданы некие поля…»)
 
 
(не показаны 4 промежуточные версии 3 участников)
Строка 3: Строка 3:
 
== Задача ==
 
== Задача ==
  
Предположим у товаров по группам заданы некие поля и необходимо выбрать те товары, у которых в одной группе полей либо одно поле равно указанному значению, либо другое, при этом, одновременно должно выполняться условие, что в другой группе полей одно или второе поле равно заданному значению, т.е. получится условие вида (А или В) и (С или D). Одним запросом при помощи selector, использую два раза режим or-mode такую выборку сделать не получится.
+
Предположим у товаров по группам заданы некие поля и необходимо выбрать те товары, у которых в одной группе полей либо одно поле равно указанному значению, либо другое, при этом, одновременно должно выполняться условие, что в другой группе полей одно или второе поле равно заданному значению, т.е. получится условие вида (А или В) и (С или D). Одним запросом при помощи selector, используя два раза режим or-mode такую выборку сделать не получится, так как между двумя условиями "ИЛИ" система поставит еще одно.
  
 
== Решение ==
 
== Решение ==
Например, найдем все объекты каталога,у которых либо поле "цена", либо поле "вес" равно 310(fields)
+
Реализовать такую выборку в UMI.CMS  можно сделав два запроса к базе и получить "пересечение" их результатов, т.е. id товаров, а затем отобрать в результирующем запросе товары с данными id:
Важно: необходимо  точно идентификатор типа в выборке. Т.е., если у Вас родительский тип-"объект каталога", а поля, по которым производится выборка находятся, например, в типе "холодильники", и идентификатор типа в выборке  указывается как идентификатор родительского типа, то в результате получим ошибку: <span style="font-weight:bold">Ошибка (selectorException): Field "имя_поля" is not presented in selected object types</span>:
 
  
 
<source lang="php">
 
<source lang="php">
$pages = new selector('objects');
+
 
$pages->types('object-type')->id(119);  
+
$pages = new selector('pages');
$pages->option('or-mode')->fields('price','weight');  
+
$pages->types('object-type')->id('идентификатор нужного типа данных');  
$pages->where('price')->equals(310);  
+
 
$pages->where('weight')->equals(310);
+
$pages->option('or-mode')->fields('поле_первой_группы1','поле_первой_группы2');
 +
 
 +
$pages->where('поле_первой_группы1')->equals('значение');
 +
 
 +
$pages->where('поле_первой_группы2')->equals('значение');
 +
 
 +
 
 +
foreach($pages as $page){
 +
 +
$mass[]=$page->id;
 +
 +
}
 +
 
 +
 +
$pages1 = new selector('pages');
 +
$pages1->types('object-type')->id('идентификатор нужного типа данных'); 
 +
 
 +
$pages1->option('or-mode')->fields('поле_второй_группы1','поле_второй_группы2');
 +
 
 +
$pages1->where('поле_второй_группы1')->equals('значение');
 +
 
 +
$pages1->where('поле_второй_группы2')->equals('значение');
 +
 
 +
 
 +
foreach($pages1 as $page1){
 +
 +
$mass2[]=$page1->id;
 +
}
 +
 
 +
 
 +
$diff = array_intersect($mass,$mass2);
 +
 
 +
$final = new selector('pages'); 
 +
$final->types('object-type')->id('идентификатор нужного типа данных');
 +
$final->where('id')->equals($diff);
 +
 +
 
 +
foreach($final as $object){
 +
 +
echo "<a href=\"{$object->link}\">{$object->name}</a>\n";
 +
}
 +
echo "Pages found: {$final->length}"; 
 +
 
 
</source>
 
</source>
 +
[[category:Вопросы и уроки разработки сайтов на UMI.CMS]]

Текущая версия на 14:23, 16 июля 2018

Актуально для версии 2.9.6

Задача

Предположим у товаров по группам заданы некие поля и необходимо выбрать те товары, у которых в одной группе полей либо одно поле равно указанному значению, либо другое, при этом, одновременно должно выполняться условие, что в другой группе полей одно или второе поле равно заданному значению, т.е. получится условие вида (А или В) и (С или D). Одним запросом при помощи selector, используя два раза режим or-mode такую выборку сделать не получится, так как между двумя условиями "ИЛИ" система поставит еще одно.

Решение

Реализовать такую выборку в UMI.CMS можно сделав два запроса к базе и получить "пересечение" их результатов, т.е. id товаров, а затем отобрать в результирующем запросе товары с данными id:

	$pages = new selector('pages');  
	$pages->types('object-type')->id('идентификатор нужного типа данных');   

	$pages->option('or-mode')->fields('поле_первой_группы1','поле_первой_группы2');

	$pages->where('поле_первой_группы1')->equals('значение');

	$pages->where('поле_первой_группы2')->equals('значение');


	foreach($pages as $page){ 
	
	$mass[]=$page->id;
		
	} 

 
	$pages1 = new selector('pages');  
	$pages1->types('object-type')->id('идентификатор нужного типа данных');   

	$pages1->option('or-mode')->fields('поле_второй_группы1','поле_второй_группы2');

	$pages1->where('поле_второй_группы1')->equals('значение');

	$pages1->where('поле_второй_группы2')->equals('значение');


	 foreach($pages1 as $page1){
	 
		$mass2[]=$page1->id;
	} 


	$diff = array_intersect($mass,$mass2);

	$final = new selector('pages');  
	$final->types('object-type')->id('идентификатор нужного типа данных'); 
	$final->where('id')->equals($diff);
	

	foreach($final as $object){
	
	echo "<a href=\"{$object->link}\">{$object->name}</a>\n";
	} 
	echo "Pages found: {$final->length}";