【问题标题】:Codeigniter Active Record - Count Total Found Rows with Limit (MySQL)Codeigniter Active Record - 计算找到的总行数(MySQL)
【发布时间】:2013-05-09 09:13:22
【问题描述】:

我在 Codeigniter 模型中使用了一个复杂的 SQL 查询,并应用了限制。如果没有应用限制和偏移量,我想计算将找到的总行数。

我想将计数连同结果数组一起返回给我的控制器 - 我该怎么做?如果这是正确的解决方案,我应该将 SQL_CALC_FOUND_ROWS 放在哪里?

这是查询(最初不是我自己构建的):

$this->db
  ->select('table1.*
      ,table2.*
      ,table3.*
      ,table4.*
      ,table5.*
      ,table6.*
      ,table7.*
      ,table8.*
      ,table9.*
      ,(SELECT GROUP_CONCAT(field1) FROM table10 WHERE table10.field3 = table9.field2) as categories
      ,(SELECT GROUP_CONCAT(field1) FROM table5 WHERE table5.field11 = table4.field12 AND table4.field21 = 0 AND table5.field1 != 0) as categories2
      ,(SELECT AVG(table11.field4) FROM table11 WHERE table11.field6 = table9.field2) as rating
      ,(SELECT COUNT(table12.field5) FROM table12 WHERE table12.field7 = table9.field2) as rated_times')
  ->from('table9')  
  ->join('table10', 'table10.field3 = table9.field2')
  ->join('categories', 'categories.field1 = table10.field1')
  ->join('table3', 'table3.field8 = table9.field2')
  ->join('table1', 'table1.id = table9.field2')
  ->join('table2', 'table2.field9 = table9.field2 AND table2.field19 = 1', 'left')
  ->join('table4', 'table4.field10 = table9.field2 AND table4.field21 = 0', 'left')
  ->join('table5', 'table5.field11 = table4.field12 AND table5.field1 != 0', 'left')
  ->join('table6', 'table6.field13 = table9.field2 AND table6.field22 BETWEEN SYSDATE() - INTERVAL 90 DAY AND SYSDATE()', 'left')
  ->join('table7', 'table7.field14 = table9.field2', 'left')
  ->join('table8', 'table8.field15 = table9.field2', 'left')
  ->where('table1.field16', NULL)
  ->where($where_clause_1, null, FALSE)
  ->where('table9.field17', $searchArray['search_country'])
  ->or_where($or_where_clause_2, null, FALSE)
  ->or_where($or_where_clause_3, null, FALSE)
  ->or_where($or_where_clause_4, null, FALSE)
  ->or_where($or_where_clause_5, null, FALSE)
  ->or_where($or_where_clause_6, null, FALSE)
  ->or_where($or_where_clause_7, null, FALSE)
  ->like('table9.field17', $searchArray['search_country'])
  ->order_by('table3.field18', 'ASC')
  ->order_by('table2.field19', 'DESC')
  ->order_by('table1.field20', 'DESC')
  ->group_by('table9.field2')
  ->limit($limit, $offset);    


  $data = $this->db->get();

return $data->result_array();

非常感谢任何帮助!

【问题讨论】:

标签: php mysql codeigniter limit codeigniter-2


【解决方案1】:

我以前对分页有完全相同的要求,我能够使用 CodeIgniter Active Record 使其工作。

首先,将选项SQL_CALC_FOUND_ROWS设置为select语句中的伪列,并将转义查询设置为false:

$this->db->select('SQL_CALC_FOUND_ROWS null as rows, other columns ...',FALSE);

然后,在使用限制和偏移量执行查询后,将结果集分配给返回数组:

$data = $this->db->get();
$return['results'] = $data->result();
// Do something with the results

最后,运行第二个查询以获取找到的行并将其分配给返回数组。我在这里使用方法链来一步完成。

$return['rows'] = $this->db->query('SELECT FOUND_ROWS() count;')->row()->count;

并返回结果和行数数组。

return $return;

【讨论】:

  • 你是我今天的英雄 :)
  • 如果您使用自定义结果对象 (custom_result_object()),则可能会出现问题,即 select 语句将另一个属性添加到行对象/数组。在这种情况下,您可以执行以下操作:$sql = $this->db->get_compiled_select(); $sql = substr_replace ($sql, ' SQL_CALC_FOUND_ROWS', 6, 0); $data = $this->db->query ($sql); 其余部分与@Wolf 建议的相同。
【解决方案2】:

我能想到的一种方法是在调用函数时使用变量 $count,它会变成这样:

function your_function($count = FALSE) {

$this->db->select(...)

//before limit you do this:

if($count != FALSE):

return $this->db->get->result_array()

else :

return $this->db->limit($limit, $offset)->get()->result_array();

endif;
}

这样你可以调用函数两次——一次用于计数,另一次用于限制查询:

$count = count($this->your_function(TRUE));
$data['query] = $this->your_function();

【讨论】:

  • 谢谢,但我试图避免调用该函数两次 - 这将涉及运行两次查询,这将是低效的
  • 我设法找到了与您类似的问题和解决方案:link
  • 我见过那个,但很难使用 SQL_CALC_FOUND_ROWS,可能是由于我正在使用的查询的复杂性
  • 嗯,也许您应该使用经典查询,而不是 CI 活动记录。我想这样你可以设法插入 SQL_CALC_FOUND_ROWS。
  • 我将经典查询转换为活动记录,因为我需要停止 CI 将反引号应用于查询,即使编写为经典查询,它仍然会这样做,但您可以通过使用可选参数来阻止它活动记录
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-07-21
  • 1970-01-01
  • 2014-06-26
  • 2010-11-16
  • 2015-06-24
  • 1970-01-01
  • 2012-03-24
相关资源
最近更新 更多