【问题标题】:Codeigniter - Limit items in query "where_in"Codeigniter - 限制查询“where_in”中的项目
【发布时间】:2014-05-25 17:53:04
【问题描述】:

我想限制每个 id 的结果(数组 id 只有 3 个结果)。

如果我添加:

$this->db->limit(3);

我总共收到三条记录;但我希望每个 id 有 3 条记录。

我该怎么办?

<?php

$array = array('id' => 1, 'id' => 2, 'id' => 3);

class Your_model extends CI_Model
{
    public $db;
    public function __construct()
    {
       parent::__construct();
       $this->db = $this->load->database('default',true);     
    }

    public function function_name()
    {
        $this->db->select('file_name');
        $this->db->from('images_table');
        $this->db->where_in('id', $array);            
        $query = $this->db->get();                  

        $result = "";
        if($query->num_rows() > 0)
            $result = $query->result_array();
        else
            $result = "No result";

        print_r($result);
    }
}

【问题讨论】:

    标签: php mysql codeigniter activerecord


    【解决方案1】:

    有两种方法可以获取每个组的 n 条记录,即数组中的每个 id 都是一个组,可以有许多与之关联的文件名。

    第一种方法

    使用 mysql 的 GROUP_CONCATSUBSTRING_INDEX 的组合。它的作用 GROUP_CONCAT 将连接列中的所有值,即 file_name 与您可以根据需要定义的分隔符,在下面的查询中我已使用双管道||,第二个SUBSTRING_INDEX 限制为3 将从GROUP_CONCAT 提供的字符串中获取提供的分隔符的3 个位置

    但请注意,GROUP_CONCAT 的默认限制为 1024 个字符,因此如果每个 id 有很多文件名,它们将被截断,但可以通过设置 GROUP_CONCAT 手册中定义的会话变量来增加 GROUP_CONCAT 的默认限制

    SELECT 
    SUBSTRING_INDEX(
    GROUP_CONCAT( file_name SEPARATOR '||'),
    '||',3) images
    FROM images_table p
    GROUP BY p.id
    

    您可以在下面提供的演示中查看示例结果

    现在在您的应用程序级别,您只需遍历产品并按分隔符拆分图像

    活动记录查询

    $results=$this->db->select('SUBSTRING_INDEX(
    GROUP_CONCAT( file_name SEPARATOR '||'),
    '||',3) images',FALSE)
         ->from('images_table p')
         ->group_by('p.id')
         ->get()
         ->result_array();
    
    foreach($results as $row):
    $images =explode('||',$row['images ']);
        foreach($images as $m):
        ....
        endforeach;
    endforeach;
    

    Demo

    第二种方法

    您可以在查询中使用用户定义的变量来对每个组的项目进行排名的其他方法

    SELECT file_name,rank FROM(
    SELECT file_name,
    @r:= CASE WHEN id = @g THEN @r+1  ELSE @r:=1 END rank 
    ,@g:=id
    FROM images_table,(SELECT @r:=0,@g:=0) t
    ORDER BY id
      ) t
     WHERE rank < 4
    

    现在这个查询不能用活动记录写,所以你必须使用简单的query()函数

        $results=$this->db
               ->query('SELECT file_name,rank FROM(
                        SELECT file_name,
                        @r:= CASE WHEN id = @g THEN @r+1  ELSE @r:=1 END rank 
                        ,@g:=id
                        FROM images_table,(SELECT @r:=0,@g:=0) t
                        ORDER BY id
                        ) t
                        WHERE rank < 4');
    

    您可以在下面提供的演示中查看示例结果

    Demo

    从 cmets 编辑

    要传递您的 id 数组,只需使用活动记录的 where_in()

    $results=$this->db->select('SUBSTRING_INDEX(
    GROUP_CONCAT( file_name SEPARATOR '||'),
    '||',3) images',FALSE)
         ->from('images_table p')
         ->where_in('p.id', $array)
         ->group_by('p.id')
         ->get()
         ->result_array();
    

    对于原始查询,您可以这样做

        $results=$this->db
               ->query('SELECT file_name,rank FROM(
                        SELECT file_name,
                        @r:= CASE WHEN id = @g THEN @r+1  ELSE @r:=1 END rank 
                        ,@g:=id
                        FROM images_table,(SELECT @r:=0,@g:=0) t
                        WHERE id IN('.join(",",$array).')
                        ORDER BY id
                        ) t
                        WHERE rank < 4');
    

    【讨论】:

    • 在我的具体情况下,我有一个包含“id”的数组;如何将数组传递给 codeigniter 中的查询?
    猜你喜欢
    • 2020-10-22
    • 1970-01-01
    • 2017-03-22
    • 2020-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-14
    • 1970-01-01
    相关资源
    最近更新 更多