背景
試卷查詢的時候,對應的習題有三張表,習題表(主表)、選擇題表、填空題表、問答題表....
習題: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中取值來組裝數據是否更好?
