sql根据一个字段的值不同,关联不同的表

背景

试卷查询的时候,对应的习题有三张表,习题表(主表)、选择题表、填空题表、问答题表....

习题: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中取值来组装数据是否更好?

原文地址:https://www.cnblogs.com/magic101/p/9687396.html