Given these simplified multiple choice tables where sometimes more than one answer is correct:
STUDENT_ANSWERS
AnswerID | StudentID | QuestionID | Answers
-------------------------------------------
1 | 1 | 1 | C,D
QUESTION_ANSWERS
QuestionID | Answer | Text
-------------------------------------------------
1 | A | This is answer A
1 | B | B could also be correct
1 | C | Maybe it's C?
1 | D | Definitely D!
How do I do a select which translates the answers to their descriptions?
My start:
SELECT *
FROM STUDENT_ANSWERS sa
LEFT OUTER JOIN QUESTION_ANSWERS qa ON qa.Answer IN sa.Answers???
-- Doesn't seem to work as IN requires a format of ('C','D') while I have 'C,D'
Desired output:
AnswerID | StudentID | QuestionID | AnswerDescriptions
-------------------------------------------
1 | 1 | 1 | Maybe it's C?,Definitely D!
So the descriptions simply have to replace the codes instead of getting a single line for each answer.
Your problem is the structure of table STUDENT_ANSWERS
. It should have one row per answer:
AnswerID | StudentID | QuestionID | Answer ------------------------------------------- 1 | 1 | 1 | C 2 | 1 | 1 | D
Now, assuming you can't do anything to change (read: fix) this, you can fudge it with appending a comma and using LIKE:
select *
from STUDENT_ANSWERS a
join QUESTION_ANSWERS q on ',' + a.Answers + ',' like '%,' + q.Answer + ',%'
and a.QuestionID = q.QuestionID
Note this assumes you will never ever have the text ,
in QUESTION_ANSWERS.Answer
. It will also never be able to use an index, so it's going to be slower than slow.
And if you absolutely must format this in the database to be one line, you can use STUFF
and the FOR XML PATH('')
trick to concatenate the resulting rows.
This is full working example using only T-SQL
statements. I will recommend to you to create separate function for splitting CSV
that returns row set. Also, if you are working with huge amount of data, you may want to create a CLR
function for splitting the values. Take a look to this article (there is everything you need).
DECLARE @StudentAnswers TABLE
(
[AnswerID] INT
,[StudentID] INT
,[QuestionID] INT
,[Answers] VARCHAR(256)
);
DECLARE @QuestionAnswers TABLE
(
[QuestionID] INT
,[Answer] CHAR
,[Text] VARCHAR(256)
);
INSERT INTO @StudentAnswers ([AnswerID], [StudentID], [QuestionID], [Answers])
VALUES (1, 1, 1, 'C,D')
,(2, 2, 1, 'A');
INSERT INTO @QuestionAnswers ([QuestionID], [Answer], [Text])
VALUES (1, 'A', 'This is answer A')
,(1, 'B', 'B could also be correct')
,(1, 'C', 'Maybe it''s C?')
,(1, 'D', 'Definitely D!');
SELECT SA.[AnswerID]
,SA.[StudentID]
,SA.[QuestionID]
,T.c.value('.', 'CHAR')
,QA.[Text]
FROM @StudentAnswers SA
CROSS APPLY
(
SELECT CAST('<i>' + REPLACE([Answers], ',', '</i><i>') + '</i>' AS XML) Answers
) DS
CROSS APPLY DS.Answers.nodes('i') T(c)
INNER JOIN @QuestionAnswers QA
ON SA.[QuestionID] = QA.[QuestionID]
AND T.c.value('.', 'CHAR') = QA.[Answer];
Try this
select answerid,studentid,a.QuestionID,group_concat(b.text) from student_answers a left join QUESTION_ANSWERS b on b.questionid= a.questionid and FIND_IN_SET(b.Answer, a.Answers)
group by a.questionid
Definitely it works.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.