CodeIgniter中使用UNION ALL结合ORDER BY和LIMIT报错求助
问题分析与解决方案
你的代码存在两个核心问题:
- SQL拼接错误:
$articles = $this->db->query(...)得到的是CodeIgniter的查询结果对象,不是SQL语句,后续把它和ORDER BY...字符串拼接会直接导致语法错误。 - 排序分页逻辑错误:你需要对合并后的全部数据整体排序后再分页,而不是先查全量数据再处理;同时直接查全量数据统计总数,数据量大时性能会很差。
修正后的完整代码
// 1. 构建两个表的查询SQL字符串(仅拼接,不执行) $this->db->select("id,article_type,title,main_img1,open_date"); $this->db->from('table1'); $query1 = $this->db->get_compiled_select(); $this->db->reset_query(); $this->db->select("id,article_type,title,main_img1,open_date"); $this->db->from('table2'); $query2 = $this->db->get_compiled_select(); $this->db->reset_query(); // 拼接UNION ALL的完整SQL(用括号包裹子查询,确保排序分页作用于合并后的整体) $union_sql = "($query1) UNION ALL ($query2)"; // 2. 高效统计总条数(用子查询COUNT,避免查全量数据) $count_sql = "SELECT COUNT(*) AS total FROM ($union_sql) AS combined"; $count_query = $this->db->query($count_sql); $data['total_rows'] = $count_query->row()->total; // 3. 分页配置 $page = $this->input->get('page') ? $this->input->get('page') : 1; $this->load->library("pagination"); $this->config->load('pagination', true); $config = $this->config->item('pagination'); $config['reuse_query_string'] = TRUE; $config['query_string_segment'] = 'page'; $config["base_url"] = site_url('example/index'); $config["total_rows"] = $data['total_rows']; $config["per_page"] = 9; $offset = ($page - 1) * $config["per_page"]; $this->pagination->initialize($config); $data['column_pagination'] = $this->pagination->create_links(); // 4. 分页查询合并后的数据集(对整体排序后分页) $final_sql = "$union_sql ORDER BY open_date DESC, id DESC LIMIT $offset, {$config['per_page']}"; $query = $this->db->query($final_sql); $data['article_posts'] = $query->result_array();
关键说明
- 用括号包裹两个子查询
($query1) UNION ALL ($query2),确保后续的ORDER BY和LIMIT是对整个合并后的结果集生效,而非仅作用于第二个表。 - 统计总数时使用
SELECT COUNT(*) FROM (...) AS combined,避免查询全量数据再统计,大幅提升性能。 - 始终操作SQL字符串而非查询结果对象,彻底避免语法错误。
内容的提问来源于stack exchange,提问作者Toru Kawahata
相关产品推荐
相关产品推荐

