如何获取嵌套在CodeIgniter的datamapper中的where_in子句中选择?

时间:2011-01-25 18:08:42

标签: php mysql codeigniter

我有一个MySQL查询,我已经在PhpMyAdmin / MySQL Workbench中工作了。

SELECT *
FROM (`medfacts`)    
JOIN `categories_medfacts` ON `categories_medfacts`.`medfact_id` = `medfacts`.`id`    
where title in (    
 select medfacts.title from medfacts    
JOIN `categories_medfacts` ON `categories_medfacts`.`medfact_id` = `medfacts`.`id`    
 where categories_medfacts.category_id = 2    
)     
or title in (    
 select medfacts.title from medfacts    
JOIN `categories_medfacts` ON `categories_medfacts`.`medfact_id` = `medfacts`.`id`    
 where categories_medfacts.category_id = 3    
) 

(查询获取连接表categories_medfacts中列出的具有给定类别ID的所有medfact。)

我现在需要将它传递给我的CodeIgniter项目,允许我的程序根据需要添加尽可能多的Having子句。到目前为止我所提出的查询大多是正确的。

function list_by_category($cat, $module) {
    /* Get a list of the Medfacts entries that have this category.         *
     */
    $this->db->join('categories_medfacts', 'categories_medfacts.medfact_id = medfacts.id');
    $this->where('medfacts.module_id', $module);
    /* If the category is an array, just get the articles that fall under all categories.
     * This shouldn't be more than a handful deep.
     */
    if (is_array($cat)) {
        foreach ($cat as $field => $value) {
            $this->where_in('title', "select medfacts.title from medfacts JOIN `categories_medfacts` ON `categories_medfacts`.`medfact_id` = `medfacts`.`id` where categories_medfacts.category_id = {$value}");
        }
    } else {
        $this->where('categories_medfacts.category_id', $cat);
    }
    $this->select('medfacts.title');
    return $this->get();
}

但是,我不能让它逃脱嵌套的Select语句,最终得到这个:

SELECT `medfacts`.`title`
FROM (`medfacts`)
JOIN `categories_medfacts` ON `categories_medfacts`.`medfact_id` = `medfacts`.`id`
WHERE ( 
`medfacts`.`module_id` = '2'
AND `medfacts`.`title` IN ('select medfacts.title from medfacts JOIN `categories_medfacts` ON `categories_medfacts`.`medfact_id` = `medfacts`.`id` where categories_medfacts.category_id = 2') 
AND `medfacts`.`title` IN ('select medfacts.title from medfacts JOIN `categories_medfacts` ON `categories_medfacts`.`medfact_id` = `medfacts`.`id` where categories_medfacts.category_id = 3') 
 )
AND `medfacts`.`site_id` = 1  

注意where in子句中嵌套select的引号。

有没有办法让Datamapper不能逃脱嵌套选择?或者,有没有更好的方法来实现相同的目标?或者我是不是自己写了这个问题?

我在PHP5服务器上使用CI 1.7.2和Datamapper DMZ 1.7.1(目前无法更新)。

修改:我知道简单的or where会返回与每个where案例相匹配的文章。但是,这不是我需要的。我只需要属于所有给定类别的结果。使用我当前的设置,or where会返回太多结果(包括仅属于所列类别之一的结果),并且and where不会返回任何内容(也不会返回任何内容,因为category_id可以不是“2”和“3”。

另外,我发现一个JOIN,如下面也适用于MySQL,但我也无法将其翻译成CI(我没有发布它,因为我认为上面的where in更清洁法)。

SELECT *    
FROM (`medfacts`)    
JOIN `categories_medfacts` ON `categories_medfacts`.`medfact_id` = `medfacts`.`id`    
join (    
    select medfacts.title, medfacts.id from medfacts    
JOIN `categories_medfacts` ON `categories_medfacts`.`medfact_id` = `medfacts`.`id`    
    where categories_medfacts.category_id = 2    
)  m1    
on m1.id = medfacts.id    
 join (    
    select medfacts.title, medfacts.id from medfacts    
JOIN `categories_medfacts` ON `categories_medfacts`.`medfact_id` = `medfacts`.`id`    
    where categories_medfacts.category_id = 3    
) m2    
on m2.id = medfacts.id    
where `medfacts`.`module_id` = '2'    
and medfacts.site_id = 1

1 个答案:

答案 0 :(得分:2)

我发现只有一种方法可以在CI中执行子选择 - http://heybigname.com/2009/09/18/using-code-igniters-active-record-class-to-create-subqueries/

然而,前段时间我被一位非常熟练的程序员(我的老板实际上是D)警告过,子选择非常慢并且执行多个单独的选择或者尝试进行连接(如果可能的话)要快得多。 。没有机会对其进行基准测试,所以请将其作为一个小建议:)