CakePHP在多个HABTM表中搜索

时间:2013-12-10 15:38:00

标签: mysql sql cakephp has-and-belongs-to-many

我的数据库:我有公司,其中HABTM carbrands 和HABTM 商品

我的搜索功能:

public function search() {
    $joins = array();
    // HABTM
    if (!empty($this->request->query['Carbrand'])) {
        $carbrands = array(
            'table' => 'carbrands_companies',
            'alias' => 'CarbrandsCompany',
            'type'  => 'INNER',
            'conditions' => array(
                'CarbrandsCompany.carbrand_id'  => $this->request->query['Carbrand'],
                'CarbrandsCompany.company_id = Company.id'
            ),
        );
        $joins[] = $carbrands;
    }
    if (!empty($this->request->query['Good'])) {
        $goods = array(
            'table' => 'companies_goods',
            'alias' => 'GoodsCompany',
            'type'  => 'INNER',
            'conditions' => array(
                'GoodsCompany.good_id'  => $this->request->query['Good'],
                'GoodsCompany.company_id = Company.id'
            ),
        );
        $joins[] = $goods;
    }
    // HABTM END
    $this->paginate = array(
        'fields' => array(
            'DISTINCT Company.id',
            'Company.name',
            'Company.addr',
            'Company.official',
        ),
        'limit'      => 10,
        'joins'      => $joins,
        'conditions' => array(),      
        'contain'    => array(),
        'order'      => array('Company.name' => 'asc')         
    );
    $found = $this->paginate('Company');
    if (!empty($found)) {
        $this->set('companies', $found);
    }else {
        $this->render('notfound');
    }
}

除了一件事之外它运作良好:它提供非常严格的搜索。 我需要找回所有 Carbrand A 的公司以及所有 Good B 的公司。

如果我在搜索表单中指定了必需的条件,Cake将生成以下SQL:

 SELECT DISTINCT `Company`.`id`, `Company`.`name`, `Company`.`addr`, `Company`.`official` FROM `autov`.`companies` AS `Company` 
 INNER JOIN `autov`.`carbrands_companies` AS `CarbrandsCompany` ON (`CarbrandsCompany`.`carbrand_id` = ('23') AND `CarbrandsCompany`.`company_id` = `Company`.`id`) 
 INNER JOIN `autov`.`companies_goods` AS `GoodsCompany` ON (`GoodsCompany`.`good_id` = ('1') AND `GoodsCompany`.`company_id` = `Company`.`id`) 
 WHERE 1 = 1 ORDER BY `Company`.`name` asc 
 LIMIT 10

显然0来自数据库。据我所知,这是因为我的功能非常严格,而Cake寻找的公司 Carbrand A 并且 Good B 同时。

但这不是我需要的。

以下查询获取所需结果:

SELECT DISTINCT `Company`.`id`, `Company`.`name`, `Company`.`addr`, `Company`.`official`         
FROM `auto`.`companies` AS `Company` 
INNER JOIN `auto`.`carbrands_companies` AS `CarbrandsCompany` ON
(`CarbrandsCompany`.`carbrand_id` = ('23') AND `CarbrandsCompany`.`company_id` = `Company`.`id`)

UNION

SELECT DISTINCT `Company`.`id`, `Company`.`name`, `Company`.`addr`, `Company`.`official` FROM `auto`.`companies` AS `Company` 
INNER JOIN `auto`.`companies_goods` AS `GoodsCompany` ON (`GoodsCompany`.`good_id` = ('1') AND `GoodsCompany`.`company_id` = `Company`.`id`) 
WHERE 1 = 1
LIMIT 100

如何更改我的函数以获得CakePHP生成的所需SQL查询?

1 个答案:

答案 0 :(得分:0)

听起来你正在寻找的是:

SELECT DISTINCT `Company`.`id`, `Company`.`name`, `Company`.`addr`, `Company`.`official`    
FROM `autov`.`companies` AS `Company` 
INNER JOIN `autov`.`carbrands_companies` AS `CarbrandsCompany` 
ON `CarbrandsCompany`.`company_id` = `Company`.`id`
INNER JOIN `autov`.`companies_goods` AS `GoodsCompany` 
ON `GoodsCompany`.`company_id` = `Company`.`id`
WHERE `CarbrandsCompany`.`carbrand_id` = 23  OR
`GoodsCompany`.`good_id` = 1
ORDER BY `Company`.`name` asc 
LIMIT 10

换句话说,我认为如果你将每个连接的连接条件移动到$ this-> paginate ['conditions'],它应该可以工作:

$this->paginate['conditions'] => array('OR' => array('GoodsCompany.good_id' => 1,  'CarbrandsCompany.carbrand_id' => 23));