MySQL从列中选择使用^作为分隔符

时间:2015-07-24 12:53:13

标签: mysql sql

我的问题类似于MySQL Split String and Select with results。目前我有2个表:

student

uid | subject_id | name
1   | 1^2^3^4    | a
2   | 2^3^       | b
3   | 1          | c

subject

uid | subject_name
1   | math
2   | science
3   | languange
4   | sport

我期望的结果是:

uid | name    | subject_passed
1   | a       | math, science, languange, sport
2   | b       | science, languange
3   | c       | sport

我试过这个问题:

SELECT
student.uid,
student.name, 
group_concat(subject.subject_name) as subjects_passed 
from student 
join subject on find_in_set(subject.uid,student.subject_id ) > 0
group by student.uid

返回错误:

  

#1064 - 您的SQL语法出错;检查与MySQL服务器版本对应的手册,以获得正确的语法   在find_in_set(subject.uid,student.subject_id)附近加入主题> 0   组'在第7行

我相信因为FIND_IN_SET。根据文档,此函数期望,作为分隔符。我可能会使用其他任何查询吗?

3 个答案:

答案 0 :(得分:4)

为什么不REPLACE分隔符:

SELECT
    student.uid,
    student.name,
    GROUP_CONCAT(subject.subject_name) AS subjects_passed
FROM student
JOIN subject ON FIND_IN_SET(subject.uid, REPLACE(student.subject_id, '^', ',')) > 0
GROUP BY student.uid

SQLFiddle

如果您决定对表进行反规范化,则可以直接创建联结表并生成数据:

-- Sample table structure
CREATE TABLE student_subject (
    student_id int NOT NULL,
    subject_id int NOT NULL,
    PRIMARY KEY (student_id, subject_id)
);

-- Sample query to denormalize student <-> subject relationship
SELECT
    student.uid AS student_id,
    subject.uid AS subject_id
FROM student
JOIN subject ON FIND_IN_SET(subject.uid, REPLACE(student.subject_id, '^', ',')) > 0
+------------+------------+
| student_id | subject_id |
+------------+------------+
|          1 |          1 |
|          1 |          2 |
|          1 |          3 |
|          1 |          4 |
|          2 |          2 |
|          2 |          3 |
|          3 |          1 |
+------------+------------+

答案 1 :(得分:3)

您永远不应该使用分隔符分隔符来存储数据,并且应该规范化表格并创建第3个表格以将学生存储到主题关系。

但是在目前的情况下,您可以将其作为

select
st.uid,
st.name,
group_concat(sb.subject_name) as subject_name
from student st
left join subject sb on find_in_set(sb.uid,replace(st.subject_id,'^',',')) > 0
group by st.uid

这是创建第三个表并存储关系

的选项
create table student_to_subject (id int primary key auto_increment, stid int, subid int);
insert into student_to_subject(stid,subid) values
(1,1),(1,2),(1,3),(1,4),(2,2),(2,3),(3,1);

现在,您可以从subject_id表中删除列student 所以查询变为

select
st.uid,
st.name,
group_concat(sb.subject_name) as passed_subject
from student st
join student_to_subject sts on sts.stid = st.uid
join subject sb on sb.uid = sts.subid
group by st.uid;

http://www.sqlfiddle.com/#!9/f02df

答案 2 :(得分:2)

认为您可以在调用find_in_set之前将^替换为,

SELECT
student.uid,
student.name, 
group_concat(subject.subject_name) as subjects_passed 
from student 
join subject on find_in_set(subject.uid, replace(student.subject_id,'^',',') ) > 0
group by student.uid

但是当然以这种格式存储值是非常糟糕的数据库设计。