我的问题类似于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
。根据文档,此函数期望,
作为分隔符。我可能会使用其他任何查询吗?
答案 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
如果您决定对表进行反规范化,则可以直接创建联结表并生成数据:
-- 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;
答案 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
但是当然以这种格式存储值是非常糟糕的数据库设计。