1

Тема: Вместо OR добавляется AND

Здравствуйте. Пытаюсь решить проблему с построением запроса в Propel.

У меня итоговый запрос выглядит так:

SQL (may NOT be complete): SELECT  FROM `crm_company` LEFT JOIN crm_search_company ON (crm_company.ID=crm_search_company.COMPANY_ID) WHERE crm_company.NAME REGEXP 'media' AND crm_company.ACTIVITIES REGEXP 'media' AND crm_company.COUNTRY=:p1 GROUP BY crm_company.ID ORDER BY crm_company.ID ASC LIMIT 10
Params: crm_company.COUNTRY => 'se'

Я хочу, чтобы вместо:

crm_company.NAME REGEXP 'media' AND crm_company.ACTIVITIES REGEXP 'media'

было

crm_company.NAME REGEXP 'media' OR crm_company.ACTIVITIES REGEXP 'media'

Строю этот запрос так:

$criteria = new Criteria();
$criteria = self::search_by_name2($keywords, $criteria); //Ищем в названии компании.
$criteria = self::search_by_activities2($keywords, $criteria); //Ищем в родах деятельности.
// ... Далее не относящееся к теме условие отбора по стране, группировка и др.

Ниже указанные две функции, которые модифицируют объект критерии:

protected static function search_by_name2($keywords, $criteria) {
    foreach ($keywords as $k => $keyword) {
        if (strlen($keyword) == 1) {
            $regex = self::NAME . " REGEXP '[[:<:]]" . $keyword . "[[:>:]]'";
        } else {
            $regex = self::NAME . " REGEXP '" . $keyword . "'";
        }
 
        $criteria->addOr(self::NAME, $regex, Criteria::CUSTOM);
    }
 
    return $criteria;
  }
 
  protected static function search_by_activities2($keywords, $criteria) {
    foreach ($keywords as $k => $keyword) {
        if (strlen($keyword) == 1) {
            $regex = self::ACTIVITIES . " REGEXP '[[:<:]]" . $keyword . "[[:>:]]'";
        } else {
            $regex = self::ACTIVITIES . " REGEXP '" . $keyword . "'";
        }
 
        $criteria->addOr(self::ACTIVITIES, $regex, Criteria::CUSTOM);
    }
 
    return $criteria;
  }

Что я делаю не так?

Как вы, возможно, поняли, я пишу поиск компаний в базе данных сайта. И нужно искать по ключевым словам в названии компании и родах деятельности. Причем условие должно быть ИЛИ. Если найдено или там или там, то это одна из искомых компаний.

Заранее спасибо!

2

Re: Вместо OR добавляется AND

Эххх, неужели никто не знает?
Ну что же, разобрался сам.
В таких случаях, когда нужно точно передать задумку итоговому запросу, нужно использовать объект Criterion.

В моем случае программа будет выглядеть так:

$criteria = new Criteria();
$criterion = self::search_by_name2($keywords); //Ищем в названии компании.
$criterion = self::search_by_activities2($keywords, $criterion); //Ищем в родах деятельности.
 
if (!is_null($criterion)) {
    $criteria->addAnd($criterion);
}
protected static function search_by_name2($keywords, $criterion=null) {
    $criteria = new Criteria();
 
    foreach ($keywords as $k => $keyword) {
        if (strlen($keyword) == 1) {
            $regex = self::NAME . " REGEXP '[[:<:]]" . $keyword . "[[:>:]]'";
        } else {
            $regex = self::NAME . " REGEXP '" . $keyword . "'";
        }
 
        if (is_null($criterion)) {
            $criterion = $criteria->getNewCriterion(self::NAME, $regex, Criteria::CUSTOM);
        } else {
            $criterion->addOr($criteria->getNewCriterion(self::NAME, $regex, Criteria::CUSTOM));
        }
    }
 
    return $criterion;
  }
 
  protected static function search_by_activities($keywords) {
    $company_ids = array();
    $criteria = new Criteria();
 
    foreach ($keywords as $k => $keyword) {
        if (strlen($keyword) == 1) {
            $regex = self::ACTIVITIES . " REGEXP '[[:<:]]" . $keyword . "[[:>:]]'";
        } else {
            $regex = self::ACTIVITIES . " REGEXP '" . $keyword . "'";
        }
 
        $criteria->addOr(self::ACTIVITIES, $regex, Criteria::CUSTOM);
    }
 
    $companies = self::doSelectStmt($criteria);
    while ($row = $companies->fetch(PDO::FETCH_ASSOC)) {
        array_push($company_ids, $row["ID"]);
    }
 
    return $company_ids;
  }

3

Re: Вместо OR добавляется AND

zverush пишет:

Эххх, неужели никто не знает?

Как бы Пропел перестал быть актуальным 5 лет назад. Что вы хотите, чтобы все до сих пор помнили, что там и как делать?