1

我正在处理一个连接查询,在该查询中我必须从包含逗号分隔值的列中获取数据。比如allowed_activity包含1,2,3,4,5,6 这个activity_id是允许的。

因此,在查询中,我正在检查是否允许当前活动,为此,我已经使用where_infind_in_setwhere条件下进行了尝试。

这是查询的那一部分:

$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 活动记录。

4

3 回答 3

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
于 2017-08-17T07:52:40.407 回答
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

于 2017-08-17T10:15:20.647 回答
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如果您想从多行中过滤某些值,每列都有一个值,那将是有意义的。

于 2017-08-17T07:49:30.087 回答