我正在处理一个连接查询,我必须从列中获取包含逗号分隔值的数据。像allowed_activity
包含1,2,3,4,5,6
这是允许的activity_id
。
因此,在查询中,我正在检查当前活动是否被允许,为此,我使用了where_in
并在find_in_set
条件下尝试了where
。
以下是查询的一部分:
$this->db->where_in('a.allowed_activity',$activity_id);
//And With FIND_IN_SET
$this->db->where("FIND_IN_SET($activity_id, a.allowed_activity) !=",0);
当我使用where_in
时,它并没有给我结果。但如果我使用FIND_IN_SET
,它将返回所需的结果。我认为where_in
可以完成任务,但事实并非如此。
只是想知道为什么
find_in_set
的工作方式不同于where_in
因为这两个函数的工作方式与查找数据相同,所以在逗号分隔列表中。
以下是完整的查询:
SELECT mycolumns
FROM `table1` as `ea`
LEFT OUTER JOIN `table2` as `a` ON `ea`.`package_id` = `a`.`id`
LEFT OUTER JOIN `table3` as `e` ON `ea`.`employer_id` = `e`.`id`
WHERE `ea`.`card_id` > 0
AND FIND_IN_SET(6, a.allowed_activity) !=0
AND `ea`.`id` = '6'
ORDER BY `ea`.`creation_date` DESC
我正在使用Codeigniter Active记录。
答案 0 :(得分:2)
WHERE IN
要求在查询中按字面指定值集,而不是包含逗号分隔字符串的单个值。如果你写:
WHERE 6 IN (a.allowed_activity)
它会将a.allowed_activity
视为单个值,并将其与6
进行比较,而不是将其作为一组多个值进行搜索。
FIND_IN_SET
在逗号分隔的字符串中搜索该值。
查看它的另一种方法是IN
是与=
结合的大量OR
测试的快捷方式:
WHERE x IN (a, b, c, d)
是
的缩写WHERE x = a OR x = b OR x = c OR x = d
当您像这样重写它时,您可以清楚地看到为什么它不适用于包含逗号分隔字符串的列。它只是翻译
WHERE 6 IN (a.allowed_activity)
为:
WHERE 6 = a.allowed_activity
答案 1 :(得分:1)
以下代码不正确:
$this->db->where("FIND_IN_SET($activity_id, a.allowed_activity) !=",0);
我很惊讶这甚至运行没有错误,但有一种可能性是它生成一个WHERE
子句,将一个字符串与0进行比较。当然,它们永远不会相等,所以这将是永远是真的。
如果您想调用原生FIND_IN_SET()
功能,则需要使用whereRaw()
:
$this->db->whereRaw("FIND_IN_SET($activity_id, a.allowed_activity) !=0");
此处使用WHERE IN (...)
不正确,因为您将所有值都放在一行中,与逗号分隔。如果您想要从多行中过滤某些值,每列都有一个值,那么WHERE IN
会有意义。
答案 2 :(得分:1)
FIND_IN_SET
在数组中搜索值并返回值的索引,如果函数不是0,则表示列表中存在的值。
所以代码
this->db->where("FIND_IN_SET(6, a.allowed_activity) !=",0);
表示返回a.allowed_activity中值6的索引 如果值返回值不同于0,那么值6将出现在a.allowed_activity
中 WHERE ... IN
检查集合中的值是否但不返回索引..如果值存在则返回true或false