CodeIgniter Query Builder 提供直觀的 join() 方法,支援 INNER、LEFT、RIGHT、OUTER 等多種聯結類型,並能處理複雜條件、別名、多表聯結。本文系統整理語法、參數、實戰範例與效能建議。
$this->db->join($table, $cond, $type = '', $escape = TRUE);
| 參數 | 說明 |
|---|---|
| $table | 要聯結的表名 (字串),可含資料庫前綴、別名 'users u'。 |
| $cond | ON 條件 (字串或陣列) 'u.id = o.user_id'。 |
| $type | 聯結類型:left, right, outer, inner, left outer, right outer;空字串 = INNER JOIN。 |
| $escape | 是否自動加反引號保護識別碼 (預設 TRUE)。 |
$this->db->select('users.name, orders.order_no, orders.total');
$this->db->from('users');
$this->db->join('orders', 'orders.user_id = users.id');
$query = $this->db->get();
// SQL: SELECT users.name, orders.order_no, orders.total FROM users JOIN orders ON orders.user_id = users.id
$this->db->select('p.title, c.name AS category');
$this->db->from('posts p');
$this->db->join('categories c', 'c.id = p.category_id', 'left');
$query = $this->db->get();
// 無分類的文章仍會列出,category 為 NULL
$this->db->select('u.name, o.order_no, oi.product_name, oi.qty');
$this->db->from('users u');
$this->db->join('orders o', 'o.user_id = u.id');
$this->db->join('order_items oi', 'oi.order_id = o.id');
$this->db->join('products pr', 'pr.id = oi.product_id', 'left');
$query = $this->db->get();
$this->db->select('u.id AS user_id, u.name, c.id AS cat_id, c.name AS cat_name');
$this->db->from('users u');
$this->db->join('categories c', 'c.id = u.category_id');
$this->db->join('logs l', [
'l.user_id = u.id',
'l.type' => 'login',
'l.created_at >' => '2024-01-01'
]);
$sub = $this->db->select('user_id, COUNT(*) AS cnt')
->from('orders')
->group_by('user_id')
->get_compiled_select(); // 取得 SQL 字串
$this->db->select('u.name, COALESCE(o.cnt, 0) AS order_count');
$this->db->from('users u');
$this->db->join("($sub) o", 'o.user_id = u.id', 'left');
$this->db->join('profiles p', 'p.user_id = u.id');
$this->db->where('p.status', 'active'); // 等同於 ON 條件延伸
SELECT * 造成網路/記憶體浪費。EXPLAIN 檢查 type = ref/eq_ref。LIMIT 100000, 20 深分頁效能崩塌。join() 多參數,請升級至 3.1+。GROUP BY 或 DISTINCT,或改用子查詢聚合。echo $this->db->last_query(); // 顯示最後執行的完整 SQL
輸出範例:
SELECT `u`.`name`, `o`.`order_no` FROM `users` AS `u` LEFT JOIN `orders` AS `o` ON `o`.`user_id` = `u`.`id`