在mysql查询中获取逗号分隔字段

时间:2014-02-25 07:04:13

标签: php mysql

我的表ID和技能值是

      1=>3 
      2 =>5
      3 =>5,6,8

我已经尝试过查询从我的表中获取值

SELECT * FROM mytable WHERE skillid IN ('3', '5');

但我只得到两行,即第一行和第二行。

但我需要结果三行。

提前致谢。

4 个答案:

答案 0 :(得分:2)

'IN'比较运算符的作用类似于相等运算符。这样:

expr IN ('3','5')

相当于:

( expr = '3' OR expr = '5' )

这应该足以解释为什么您的查询没有返回您期望的内容。


如果您的表具有包含逗号分隔列表的字符列,请执行以下操作:

id  skill_id_list
--  -------------
 1  3
 2  5
 3  5,6,8

然后,在列表中搜索特定id值的一个选项是使用MySQL FIND_IN_SET函数。例如:

SELECT t.id
     , t.skill_id_list
  FROM mytable t
 WHERE FIND_IN_SET('3', t.skill_id_list)
    OR FIND_IN_SET('5', t.skill_id_list)

这里记录了MySQL FIND_IN_SET函数:

https://dev.mysql.com/doc/refman/5.5/en/string-functions.html#function_find-in-set

当然,这只是一个选择。还有其他几种方法可以获得相同的结果。

如果skill_id_list列中没有空格,则另一个选项是使用LIKE运算符,但要注意处理边缘情况。

有四种情况需要检查出现的id值:

  • 是列表中唯一的一个
  • 在列表的开头
  • 位于列表中间
  • 列表末尾的

要明确处理这四种情况,您可以检查每种情况,例如:

 WHERE skill_id_list LIKE '3'        -- only one in list
    OR skill_id_list LIKE '3,%'      -- beginning of list
    OR skill_id_list LIKE '%,3,%'    -- middle of list
    OR skill_id_list LIKE '%,3'      -- end of list

或者,另一种方法是将所有这些案例转换为单个“列表中间”,只需在列表的开头和结尾添加逗号,然后执行单个检查,例如:

 WHERE CONCAT(',',skill_id_list,',') LIKE '%,3,%'

请注意,列表中嵌入的空格可能会导致行不匹配。 MySQL REPLACE函数可用于删除空格,用空字符串替换所有空格,如下所示:

 WHERE CONCAT(',',REPLACE(skill_id_list,' ',''),',') LIKE '%,3,%'

注意

前面的尝试回答你问的问题。以下是关于关系数据模型和规范化的根本不同(虽然密切相关)的问题。

规范化关系模型中的重复属性在单独的表中表示。这是规范的关系模型。我们通常避免存储以逗号分隔的列表,而是实现一个单独的表来存储重复的属性。

例如,如果job有多种技能,我们通常会创建另一个表来保存工作技能列表:

CREATE TABLE job 
( id  INT NOT NULL PRIMARY KEY
, description VARCHAR(10)
);

CREATE TABLE job_skill 
( job_id   INT NOT NULL COMMENT 'FK ref job.id'
, skill_id INT NOT NULL COMMENT ''
, PRIMARY KEY (job_id, skill_id)
, FOREIGN KEY job_skill_FK1 (job_id) REFERENCES job (id)
);

我们将模型中的数据表示为五个单独的行:

job_skill
job_id  skill_id
------  --------
1       3
2       5
3       5
3       6
3       8

这是规范模式。

获取需要技能3或5的工作ID列表:

SELECT s.job_id
  FROM job_skill s
 WHERE s.skill_id in (3,5)
 GROUP BY j.job_id

要获取需要技能3和5的工作ID列表,有几种方法可以做到这一点,例如:

SELECT s.job_id
  FROM job_skill s
    ON s.job_id = t
 WHERE s.skill_id in (3,5)
 GROUP BY j.job_id
HAVING COUNT(DISTINCT s.skill_id) = 2

如果您的用例更方便将逗号分隔列表作为字符串返回,则可以使用GROUP_CONCAT聚合函数:

SELECT j.id AS job_id
     , GROUP_CONCAT(s.skill_id ORDER BY s.skill_id) AS skill_id_list
  FROM job j
  LEFT
  JOIN job_skill s
    ON s.job_id = j.id
 WHERE ...
 ORDER BY ...

答案 1 :(得分:1)

请检查

SELECT * FROM mytable WHERE 5 IN(技能)或3 IN(技能);

答案 2 :(得分:0)

SELECT * FROM mytable WHERE skillid LIKE'3%'或skillid LIKE'5%';

绝对不是这样做的方式......

你应该正常化你的桌子以避免这种问题

答案 3 :(得分:0)

这不是一个好习惯,你应该规范化你的桌子表,但REGEXP会有所帮助

请尝试这种方式

SELECT * FROM mytable WHERE 
skillid REGEXP '[[:<:]]3[[:>:]]' OR skillid REGEXP '[[:<:]]5[[:>:]]'