Как получить вложенные объекты Select в предложении where_in в преобразователе данных CodeIgniter? - PullRequest
1 голос
/ 25 января 2011

У меня есть запрос 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    
) 

(Запрос получает все медфакты, перечисленные в объединяющей таблице category_medfacts с указанными идентификаторами категорий.)

Теперь мне нужно перенести его в мой проект CodeIgniter таким образом, чтобыПозволяет моей программе добавлять столько предложений, сколько необходимо.То, что я до сих пор генерирую, генерирует запрос в основном правильно.

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.

Есть ли способ заставить Datamapper не экранировать этот вложенный выбор?Или есть лучший способ достичь той же цели?Или я застрял при написании запроса сам?

Я использую CI 1.7.2 и Datamapper DMZ 1.7.1 (обновление в настоящее время не обсуждается) на серверах PHP5.

Редактировать: Мне известно, что простой 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 Ответ

2 голосов
/ 25 января 2011

я нашел только один способ выполнить подвыборы в CI - http://heybigname.com/2009/09/18/using-code-igniters-active-record-class-to-create-subqueries/

однако, некоторое время назад я был предупрежден очень опытным программистом (мой босс на самом деле: D), что отборы довольномедленный и выполнение нескольких отдельных выборок или попытка сделать объединение вместо этого (где это возможно) намного быстрее ... не было возможности сравнить его, поэтому воспринимайте это как незначительное предложение:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...