Построитель запросов QueryBuilder

#
Re: Построитель запросов QueryBuilder
Доброе время суток!
Не могу понять почему в стандартной ТДС Интернет магазина (Халява 6.1.1) при фильтрации по нескольким дополнительным свойствам значения выбираются следующим образом: допустим есть элемент с доп_свойство1=123 и доп_свойство2=312, если искать по принципу - искать элемент двум свойствам сразу и одно свойство не будет соответствовать существующему а одно соответствует, то не найдется вообще ничего. Работает как логическое условие AND. А хотелось бы что бы работало как OR. Т.е. ели хотя бы одно свойство совпало, то выводился элемент. Хотя, в самой ТДС, вроде как, установлено условие "или".
         while(list(, list($oProperty, $propertyValue)) = each($aTmpProperties))
         {
            $tableName = $oProperty->createNewValue(0)->getTableName();

            !in_array($tableName, $aTableNames) && $aTableNames[] = $tableName;

            $Shop_Controller_Show->shopItems()->queryBuilder()
               ->where('shop_item_properties.property_id', '=', $oProperty->id);

            if (!is_array($propertyValue))
            {
               // Для строк фильтр LIKE %...%
               if ($oProperty->type == 1)
               {
                  $Shop_Controller_Show->shopItems()->queryBuilder()
                     ->where($tableName . '.value', 'LIKE', "%{$propertyValue}%");
               }
               else
               {
                  // Checkbox
                  $oProperty->type == 7 && $propertyValue != '' && $propertyValue = 1;

                  $Shop_Controller_Show->shopItems()->queryBuilder()
                     ->open()
                     ->where($tableName . '.value', '=', $propertyValue)
                     ->setOr()
                     ->where($tableName . '.value', 'IS', NULL)
                     ->close()
                     ;
               }

               $Shop_Controller_Show->shopItems()->queryBuilder()
                  ->setOr();

               $Shop_Controller_Show->addEntity(
                  Core::factory('Core_Xml_Entity')
                     ->name('property_' . $oProperty->id)->value($propertyValue)
               );
               $Shop_Controller_Show->addCacheSignature("property{$oProperty->id}={$propertyValue}");
            }
            else
            {
               $from = trim(intval(Core_Array::get($propertyValue, 'from')));
               $from && $Shop_Controller_Show->shopItems()->queryBuilder()
                  ->open()
                  ->where($tableName . '.value', '>=', $from)
                  ->setOr()
                  ->where($tableName . '.value', 'IS', NULL)
                  ->close()
                  ->setAnd();

               $to = trim(intval(Core_Array::get($propertyValue, 'to')));
               $to && $Shop_Controller_Show->shopItems()->queryBuilder()
                  ->open()
                  ->where($tableName . '.value', '<=', $to)
                  ->setOr()
                  ->where($tableName . '.value', 'IS', NULL)
                  ->close();

               $Shop_Controller_Show->shopItems()->queryBuilder()
                  ->setOr();


               $Shop_Controller_Show->addEntity(
                  Core::factory('Core_Xml_Entity')
                     ->name('property_' . $oProperty->id . '_from')->value($from)
               )->addEntity(
                  Core::factory('Core_Xml_Entity')
                     ->name('property_' . $oProperty->id . '_to')->value($to)
               );

               $Shop_Controller_Show
                  ->addCacheSignature("property{$oProperty->id}_from={$from}")
                  ->addCacheSignature("property{$oProperty->id}_to={$to}");
            }
         }
  
Спасибо!
#
Re: Построитель запросов QueryBuilder
Возможно, я решил вопрос. Поменял условие в объединении с AND на OR.
         $Shop_Controller_Show->shopItems()->queryBuilder()
            ->close()
            ->groupBy('shop_items.id')
            ->having(Core_Querybuilder::expression('COUNT(DISTINCT `shop_item_properties`.`property_id`)'), '=', $havingCount);

         foreach ($aTableNames as $tableName)
         {
            $Shop_Controller_Show->shopItems()->queryBuilder()
               ->leftJoin($tableName, 'shop_items.id', '=', $tableName . '.entity_id',
                  array(
                     array('OR' => array('shop_item_properties.property_id', '=', Core_QueryBuilder::expression($tableName . '.property_id')))
                  )
               );
         }

Я прав?
#
Re: Построитель запросов QueryBuilder
Добрый день!
Не получается выборка.
Товар имеет три свойства, эти три свойства имеют значения элемента ИС.
Есть фильтр по всем элементам ИС в виде чек боксов.


Верх - 1 свойство
Лиф-сердце
Американка
Спущенная линия плеча
С брителями
Без бритель
Закрытые плечи
Открытая спина

Силуэт - 2 свойство
А-силуэт
Рыбка
Прямое
Пышное
Короткое

Шлейф - 3 свойство
со шлейфом
без шлейфа



Пытаюсь сделать фильтр по отмеченным свойствам. Сейчас у меня получается следующие, если я отмечу чекбоксами значения только в одном свойстве, то всё хорошо (например со шлейфом, без шлейфа), товар ищется, если я отмечаю в нескольких свойствах значения (например со шлейфом,
без шлейфа и Прямое,
Пышное), то товар не показывается. Где я ошибся в построение запроса?


$count = 0;
        $Shop_Controller_Show
             ->shopItems()
             ->queryBuilder()
             ->leftJoin('shop_item_properties', 'shop_items.shop_id', '=', 'shop_item_properties.shop_id')
             ->leftJoin('property_value_ints', 'shop_items.id', '=', 'property_value_ints.entity_id',
                array(
                   array('AND' => array('shop_item_properties.property_id', '=', Core_QueryBuilder::expression('`property_value_ints`.`property_id`')))
                )
             );
        
        foreach( $_GET['property'] as $id=>$aValue) {
            
            $Shop_Controller_Show
             ->shopItems()
             ->queryBuilder()
             ->where('shop_item_properties.property_id', '=', $id)
             ->where('property_value_ints.value', 'IN', $aValue);
            
            $count++;
        }
        
        
        $Shop_Controller_Show
             ->shopItems()
             ->queryBuilder()
            
             ->groupBy('shop_items.id')
             // Количество свойств
             ->having(Core_Querybuilder::expression('COUNT(DISTINCT `shop_item_properties`.`property_id`)'), '=', $count);
        
            
    $Shop_Controller_Show->group(FALSE);
   $Shop_Controller_Show->groupsMode('none');

      
Сам запрос:

SELECT SQL_CALC_FOUND_ROWS `shop_items`.*
FROM `shop_items`
LEFT OUTER JOIN `shop_item_properties` ON `shop_items`.`shop_id` = `shop_item_properties`.`shop_id`
LEFT OUTER JOIN `property_value_ints` ON `shop_items`.`id` = `property_value_ints`.`entity_id` AND `shop_item_properties`.`property_id` = `property_value_ints`.`property_id`

WHERE `shop_items`.`shop_id` = '1' AND ( `shop_items`.`start_datetime` < '2014-02-13 09:17:52' OR `shop_items`.`start_datetime` = '0000-00-00 00:00:00' ) AND ( `shop_items`.`end_datetime` > '2014-02-13 09:17:52' OR `shop_items`.`end_datetime` = '0000-00-00 00:00:00' ) AND `shop_items`.`siteuser_group_id` IN (0, -1) AND `shop_items`.`modification_id` = 0

AND `shop_item_properties`.`property_id` = 63 AND `property_value_ints`.`value` IN ('151', '152', '153', '154')
AND `shop_item_properties`.`property_id` = 64 AND `property_value_ints`.`value` IN ('156', '157')

AND `shop_items`.`active` = 1 AND `shop_items`.`deleted` = 0 GROUP BY `shop_items`.`id`

HAVING COUNT(DISTINCT `shop_item_properties`.`property_id`) = 2 ORDER BY `shop_items`.`sorting` ASC, `shop_items`.`name` ASC LIMIT 16 OFFSET 0
  
d-sant.com
#
Re: Построитель запросов QueryBuilder
как можно обратиться к методам getAffectedRows() и getInsertId() после выполнения запроса?
Модератор
#
Re: Построитель запросов QueryBuilder
lezhenkin,
смотря как выполняете. Покажите код.
#
Re: Построитель запросов QueryBuilder
HostCMS


$oCore_QueryBuilder_Insert = Core_QueryBuilder::insert('table_name', array('field1' => 'value1', 'field2' => 'value2'))
   ->execute();
$lastInsertId = ?


Просто использовать функцию mysql_insert_id() ?


$update = Core_QueryBuilder::update('table_name')
   ->columns(array('field1' => 'value1', 'field2' => 'value2'))
   ->where('id', '=', $lastInsertId)
   ->limit(1)
   ->execute();


Вот, к примеру, так.
Модератор
#
Re: Построитель запросов QueryBuilder
execute() Вам вернет уже Core_DataBase, соответственно
$oCore_DataBase = Core_QueryBuilder::insert('table_name', array('field1' => 'value1', 'field2' => 'value2'))
   ->execute();
$lastInsertId = $oCore_DataBase->getInsertId();
аналогично с
getAffectedRows()
#
Re: Построитель запросов QueryBuilder
HostCMS, для вставки значений не смотрел, а вот, что возвращается при обновлении значений.

var_dump($update->getAffectedRows());    // NULL


А SQL-запрос успешно выполняется.

И execute() возвращает мне объект Core_DataBase_Mysql, а не Core_DataBase.
Модератор
#
Re: Построитель запросов QueryBuilder
lezhenkin,
Вы спрашиваете про вставку, я привожу пример. Про обновление ничего сказать не могу, ибо пример Вы показывали для вставки.
P.S. От чего Core_DataBase_Mysql унаследован сами сможете посмотреть?
#
Re: Построитель запросов QueryBuilder
Цитата:
Вы спрашиваете про вставку, я привожу пример. Про обновление ничего сказать не могу, ибо пример Вы показывали для вставки.

Ну я два примера привел, второй был для обновления
$update = Core_QueryBuilder::update('table_name')
    ->columns(array('field1' => 'value1', 'field2' => 'value2'))
    ->where('id', '=', $lastInsertId)
    ->limit(1)
    ->execute();

Вот этот запрос выполняется успешно. Но после него метод getAffectedRows() возвращает NULL.

Цитата:
P.S. От чего Core_DataBase_Mysql унаследован сами сможете посмотреть?

Конечно Но возвращается-таки объект Core_DataBase_Mysql, в котором метод getAffectedRows() и объявлен как общедоступный. Ну, суть не в этом. Возвращается NULL почему-то.
Авторизация