where_in和find_in_set

时间:2017-08-17 07:40:50

标签: mysql codeigniter where-in find-in-set

我正在处理一个连接查询,我必须从列中获取包含逗号分隔值的数据。像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记录。

3 个答案:

答案 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