如何匹配数据库中所有逗号分隔的字符串?

时间:2014-02-11 12:06:43

标签: php mysql

我想只获取所有接收者ID匹配的记录,但查询中的find_in_setIN运算符会返回包含任何ID的所有记录。

我希望只获得与我的数据库中所有all_recipients列匹配的记录。

例如,我想在以下情况下只获取 pid = 6 的记录:

我有以下查询:

 SELECT * FROM `conf_event_message_recipients` WHERE receiver IN (6622,6607) AND event_id = 46

和数据库记录:

pid  mid    seq     receiver     all_recipients     event_id    status
8    127    9       6622         6607,6622,6624     46          2
6    127    9       6622         6607,6622          46          2
9    127    9       6622         6607,6622,6624     46          2

我怎样才能做到这一点?

3 个答案:

答案 0 :(得分:2)

它不漂亮,但是当您在列表中存储列表而不是使用关联/联结表时会发生这种情况。你真的应该修复数据结构。

以下方法通过对每个值使用find_in_set()来计算字符串中的匹配数。然后将它与字符串中的项目数进行比较,使用技巧将每个逗号替换为两个字符,取长度,减去原始长度并添加一个:

SELECT *
FROM `conf_event_message_recipients`
WHERE (find_in_set(6622, all_recipients) > 0 +
       find_in_set(6607, all_recipients) > 0
      ) = (length(replace(all_recipients, ',', ',,')) - length(all_recipients) + 1) 
WHERE event_id = 46;

编辑:

还有另一种方法,也不漂亮:

select *
from conf_event_message_recipients
where replace(replace(replace(concat(',', all_recipients, ',', ',6622,', '',
                             ) ',6607,', ''
                     ), ',', ''
             ) = '' and
      event_id = 46;

也就是说,用空字符串替换每个id,然后删除逗号并确保没有任何内容。额外的逗号是为了防止“660”在替换中匹配“6607”。

答案 1 :(得分:1)

使用正常的相等比较:

SELECT *
FROM conf_event_message_recipients
WHERE all_recipients = '6607,6622'

或者如果您不能保证订单:

SELECT *
FROM conf_event_message_recipients
WHERE CHAR_LENGTH(all_recipients) - CHAR_LENGTH(REPLACE(all_recipients, ',', '')) = 1
AND FIND_IN_SET('6607', all_recipients)
AND FIND_IN_SET('6622', all_recipients)

第一个条件计算字段中逗号的数量,该值比值的数量少一个。然后剩下的条件检查每个所需的值是否在字段中。

如果表很大,这是一个非常低效的查询。您需要规范化架构以解决此问题。

答案 2 :(得分:1)

您可以使用以下查询:

SELECT * FROM `conf_event_message_recipients` WHERE all_recipients LIKE '%6622%' AND all_recipients LIKE '%6607%' AND LENGTH(all_recipients) = 9 AND event_id = 46

根据LENGTH(all_recipients)

中的元素数更改all_recipients的值
相关问题