Ограничение SQL-соединения при использовании класса активных записей CodeIgniter - PullRequest
4 голосов
/ 24 мая 2011

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

$this->db->select('p.product_id, p.product_name i.img_name, i.img_ext');    
$this->db->join('products_images i', 'i.product_id = p.product_id', 'left');
$query = $this->db->get('products p');

Есть ли возможность ограничить db-> join до 1 записи, используя класс активной записи CI?

Ответы [ 4 ]

1 голос
/ 24 мая 2011

Добавьте $this->db->limit(1); перед вызовом $this->db->get('products p');. См. Документы на ellislab.com : найдите на странице limit .

РЕДАКТИРОВАТЬ: я неправильно понял тот факт, что вы пытались применить LIMIT для внутреннего оператора JOIN.

Нет. Поскольку вы не можете выполнить LIMIT для внутреннего оператора JOIN в обычном SQL, вы не можете сделать это с помощью класса ActiveRecord Code Igniter.

0 голосов
/ 12 мая 2013

Если бы я тоже решил эту проблему, он повторял результаты и удалял текущий объект, если ранее существовал product_id.Создайте массив, добавьте к нему product_id, проверяя, являются ли они повторениями.

$product_array = array();
$i = 0;

foreach($result as $r){

    if(in_array($r->product_id,$product_array)){
        unset($result[$i]);
    }else{
        array_push($product_array,$r->product_id);
    }
    $i++;

} 

$result = array_values($result); //re-index result array

Теперь результат $ - это то, что мы хотим

0 голосов
/ 31 декабря 2012

Чтобы расширить ответ @ Femi:

Нет хорошего способа ограничить JOIN, и, на самом деле, вы на самом деле этого не хотите. Предполагая, что и у products_image.product_id, и у products.id есть индексы (и они абсолютно необходимы, если вы собираетесь объединяться с ними неоднократно), когда ядро ​​базы данных выполняет соединение, оно использует индексы, чтобы определить, какие строки ему нужно выбрать. Затем механизм использует результаты, чтобы определить, где на диске найти нужные записи. Если вы

Вы сможете увидеть разницу, запустив следующие операторы SQL:

EXPLAIN 
SELECT p.product_id, p.product_name, i.img_name, i.img_ext
FROM products p
LEFT JOIN products_images i
    ON i.product_id = p.product_id

вместо:

EXPLAIN  
SELECT p.product_id, p.product_name, i.img_name, i.img_ext
FROM (SELECT product_id, product_name FROM products) p 
LEFT JOIN (SELECT img_name, img_ext FROM products_images) i
    ON i.product_id = p.product_id

Первый запрос должен иметь индекс, а второй - нет. Должна быть разница в производительности, если в базе данных имеется значительное количество строк.

0 голосов
/ 31 декабря 2012

Вы можете достичь того, что хотите, используя $this->db->group_by с left объединением:

$this->db->select('products.id, products.product_name, products_images.img_name, products_images.img_ext');
$this->db->from('products');
$this->db->join('products_images', 'products_images.product_id = products.id', 'left');
$this->db->group_by('products.id'); 
$query = $this->db->get();

Это должно дать вам результаты на products.id (без повторения продуктов) с первой соответствующей записьюс products_images присоединяется к каждой строке результатов.Если в объединенной таблице нет подходящей строки (т. Е. Если изображение отсутствует), вы получите нулевые значения для полей products_images, но все равно увидите результат из таблицы products.

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