1

我很抱歉标题不完整——我也需要在这个标题上指出正确的方向。我正在尝试编写一个查询来搜索包含逗号分隔文本字段中的字符串的记录。我使用 MySql 和 php。

记录示例:

recordID | statuses[TEXT]
1010     | 102
1011     | 100,103
1012     | 100,106,201,300

我从另一个表status_dataset 中查询我想要搜索的雕像

statusName | statusCode | Yes/No
name1      | 100        |   
name2      | 101        |
name3      | 102        |  Yes
name3      | 103        |
name4      | 106        |  Yes

现在我想查找包含雕像 102 或 106 的所有记录

我可以分两步解决这个问题,查询我想要的状态数据集,然后连接条件部分,所以我基本上得到下一个查询:

SELECT * FROM table AS t
WHERE t.statuses LIKE '%201%'
OR t.statuses LIKE '%206%'

或者这个

SELECT * FROM table AS t 
WHERE FIND_IN_SET('201',t.statuses)
OR FIND_IN_SET('206',t.statuses)

我会得到我想要的结果:

    recordID | statuses
    1010     | 102
    1012     | 100,106,201,300

现在我想知道是否有更好的方法来解决这个问题。最好在一个查询中。或者在两个查询中,我将创建一个我想要搜索的值列表。我查看了 FIND_IN_SET(str,strlist) 函数,但问题是我需要多个 str。有没有我可以使用的函数,所以我可以用我想要搜索的多个值填充它?我一直在谷歌搜索,但恐怕我不知道如何正确提问。

4

3 回答 3

2

我刚刚又看了你的帖子,你说的是“或”而不是“和”。以下查询查找您要查找的记录:

select distinct r.*
from records r join
     statuses_dataset d
     on concat(',', r.statuses, ',') like concat('%,', d.status, ',%') and
        d.use = 'Yes'

我将 like 更改为在状态字符串之前和之后包含逗号。这允许查询搜索“,105”而不是“105”,以防止匹配“1050”等。

如果您改变主意并想要具有所有状态的记录,那么查询会稍微复杂一些。在这里,子查询匹配首先查找与代码匹配的所有记录。然后它计算匹配的数量并返回匹配所有单个代码的记录。

with matches as (select r.RecordId, count(distinct d.statuscode) as num_matches
                 from records r join
                      statuses_dataset d
                      on concat(',', r.statuses, ',') like concat('%,', d.status, ',%') and
                         d.use = 'Yes'
                 group by r.RecordId
                )
select r.*
from records r cross join
     (select count(distinct d.statuscode) as numyes
      from statuses_dataset
      where d.use = 'Yes'
     ) ssum join
     matches m
     on r.RecordId = m.Recordid and
        m.nummatches = ssum.numyes

使用 count distinct 而不是 count(*) 只会处理状态表中的重复项。

于 2012-07-22T13:21:36.627 回答
0

我认为你最好规范化你的数据库模式(当还不算太晚的时候),并存储像这样ID, recordID, status的行,一个记录ID-状态关系的一行。这将使您可以通过简单(且更有效)的WHERE status in (X, Y, Z)子句过滤您的状态。不要忘记索引recordIDstatus字段。

通过一些一次性脚本运行,将当前数据集转换为标准化状态应该非常简单。

于 2012-07-22T12:40:49.793 回答
0

尝试使用该GROUP_CONCAT()功能

SELECT recordID ,
       GROUP_CONCAT(statuses)
       FROM MyTable
       GROUP BY recordID ;
于 2012-07-22T12:41:03.807 回答