CodeIgniter 3 Query Builder的join方法使用!=运算符未得预期结果
解决CodeIgniter 3 Query Builder筛选无关联分类记录的问题
你现在的问题出在用INNER JOIN搭配!=运算符的思路上——INNER JOIN的逻辑是只保留两张表中匹配连接条件的行,而!=会把所有category_level_2.cat_lvl1_id不等于category_level_1.id的行都关联起来,这就导致原本没有关联的level1分类,会和level2里所有不匹配的行重复关联,最终结果里还是会包含所有level1的记录,完全达不到你要的「只保留level2中无对应记录的level1分类」的效果。
给你两种正确的实现方式,都用CodeIgniter 3的Query Builder来写:
方案一:LEFT JOIN + 筛选NULL值
这是最常用的方式,用左连接把level1和level2关联,然后筛选出level2中没有匹配的记录(也就是level2的字段为NULL的行):
$query = $this->db ->select('category_level_1.id, category_level_1.category') ->from('category_level_1') ->join('category_level_2', 'category_level_2.cat_lvl1_id = category_level_1.id', 'left') ->where('category_level_2.cat_lvl1_id IS NULL') ->group_by('category_level_1.id') ->get();
原理:LEFT JOIN会保留level1的所有记录,然后匹配level2中对应的行;如果level2里没有对应cat_lvl1_id的记录,那level2的字段就会是NULL,我们筛选这些NULL的行,就是你要的无关联记录。
方案二:使用NOT EXISTS子查询
这种方式逻辑更直观,直接查询level1中「不存在于level2的cat_lvl1_id」的记录:
$query = $this->db ->select('category_level_1.id, category_level_1.category') ->from('category_level_1') ->where_not_exists("SELECT 1 FROM category_level_2 WHERE category_level_2.cat_lvl1_id = category_level_1.id") ->get();
原理:子查询会检查当前level1的id是否在level2的cat_lvl1_id中存在,where_not_exists会保留那些子查询返回空的level1记录,也就是无关联的分类。
这两种方式都能得到你想要的预期输出,选哪种都可以,看你更习惯哪种逻辑~
内容的提问来源于stack exchange,提问作者Pasindu Jayanath
相关产品推荐
相关产品推荐

