背景
试卷查询的时候,对应的习题有三张表,习题表(主表)、选择题表、填空题表、问答题表....
习题:XTEL_Exercises(习题)
ID | int | 习题ID |
UploaderID | int | 上传者ID |
Type | int | 习题类型 0 – 选择题 1 – 问答题 2 – 填空题 |
RecordID | int | 在实际对应类型的习题表中,习题记录的ID |
UploadTime | int | 上传时间,以s为单位的时间戳 |
Brief | TEXT | 习题摘要 |
选择题表:XTEL_Exer_ChoiceQuestion(选择题)
名称 | 类型 | 说明 |
ID | int | 习题记录ID |
Stem | TEXT | 题干 |
NumberOfOptions | int | 选项个数 |
MaxOptions | int | 最大选择数 |
MinOptions | int | 最小选择数 |
Option1 | TEXT | 选项1 |
Option2 | TEXT | 选项2 |
Option3 | TEXT | 选项3 |
Option4 | TEXT | 选项4 |
Option5 | TEXT | 选项5 |
Option6 | TEXT | 选项6 |
ReferenceAnswer | TEXT | 参考答案 |
填空题表:XTEL_Exer_FillupQuestion(填空题)
名称 | 类型 | 说明 |
ID | int | 习题记录ID |
Stem | TEXT | 题干 |
GapPos | TEXT | 待填写答案的空白处在题干中的位置,是一串json字符串 |
GapNumber | int | 空白个数 |
ReferenceAnswer | TEXT | 参考答案 |
|
|
需要查询试卷:方法1:根据类型不同去分别查询,后台进行组装(暂不考虑)
方法2:sql一次性查询出来,首先想到decode、case...when....
decode
select a.*,decode(a.type,0,(select b.Stem from XTEL_Exer_ChoiceQuestion b where b.id=a.id)) from XTEL_Exercises a ---decode中只能有一列
case...when....
SELECT CASE WHEN a.type=0 THEN (SELECT b.Stem FROM XTEL_Exer_ChoiceQuestion b WHERE a.id=b.id) end case ,a.* from XTEL_Exercises a --同上
注意:decode,case...when 关联表都只能查询一列,这里明显不满足要求。
UNION ALL
之后又想到union all
SELECT b.Stem,b.ReferenceAnswerFROM XTEL_Exercises a join XTEL_Exer_ChoiceQuestion b on a.id=b.id where a.type = 0 UNION ALL SELECT c.Stem,c.ReferenceAnswer FROM XTEL_Exercises a join XTEL_Exer_EssayQuestion c on a.id=c.id AND a.type = 1
限制:union all需要每个返回的列都相同,其他地方可以加别名。但是这里我们发现选择题表需要查询的列明显多于填空题。
解决:不存在的字段赋值null,取别名。
select c.stem,c.Option1,c.Option2,c.ReferenceAnswer from XTEL_Exer2ExamPaper a join XTEL_Exercises b on a.ExerID=b.id
join XTEL_Exer_ChoiceQuestion c on b.id=c.id
where b.type=0
union all
select c.ReferenceAnswer,null option1,null option2,c.stem from XTEL_Exer2ExamPaper a join XTEL_Exercises b on a.ExerID=b.id
join XTEL_Exer_EssayQuestion c on b.id=c.id
where b.type=1
思考:上面的解决方法其实都不完美,试卷创建成功后,是否可以分类查询,放入redis中,后台从redis中取值来组装数据是否更好?