我正在开发一个允许配置问题和答案的应用程序。目前最多可以有20个答案,但可能更少。
我的结构如下:
+----+--------+--------------+-------------+ | ID | FormId | QuestionText | AnswerField | +----+--------+--------------+-------------+ | 1 | 1 | Name | Answer01 | | 2 | 1 | Address | Answer02 | | 3 | 1 | Phone | Answer03 | | 4 | 1 | Email | Answer04 | | 5 | 2 | First Name | Answer01 | | 6 | 2 | Surname | Answer02 | +----+--------+--------------+-------------+
+----+--------+----------+------------+--------------+--------------+----------------+----------+----------+ | ID | FormId | RecordId | Answer01 | Answer02 | Answer03 | Answer04 | Answer05 | Answer06 | +----+--------+----------+------------+--------------+--------------+----------------+----------+----------+ | 1 | 1 | 1 | Bob Smith | Bobs Address | 01234 111222 | bob@smith.com | Null | Null | | 2 | 1 | 2 | Joe Bloggs | Joes Address | 04321 333444 | joe@bloggs.com | Null | Null | | 3 | 2 | 3 | David | Jones | Null | Null | Null | | +----+--------+----------+------------+--------------+--------------+----------------+----------+----------+
因此,在Questions表中AnswerField Answer01映射到Answers表中的Answer01列
我想做的就是得到一个看起来像这样的结果集:
对于表格ID 1和记录ID 1:
+--------------+---------------+ | QuestionText | Answer | +--------------+---------------+ | Name | Bob Smith | | Address | Bobs Address | | Phone | 01234 111222 | | Email | bob@smith.com | +--------------+---------------+
然后对于表单ID 2和记录ID 3:
+--------------+---------+ | QuestionText | Answer | +--------------+---------+ | First Name | David | | Surname | Jones | +--------------+---------+
我尝试使用数据透视表:
SELECT QuestionText, Answer01, Answer02, Answer03, Answer04 FROM ( SELECT DISTINCT Q.AnswerField, Q.QuestionText, Q.ID, A.Answer01, A.Answer02, A.Answer03, A.Answer04 FROM Questions Q INNER JOIN Answers A ON A.FormId= Q.FormId WHERE A.ID = 17 ) AS src PIVOT (MAX(question_id) FOR Answer IN(answer_01, answer_02, answer_03, answer_04)) AS pvt
但这在所有列中都重复了答案:
+--------------+-----------+--------------+--------------+---------------+ | QuestionText | Answer01 | Answer02 | Answer03 | Answer04 | +--------------+-----------+--------------+--------------+---------------+ | Name | Bob smith | Bobs Address | 01234 111222 | bob@smith.com | | Address | Bob smith | Bobs Address | 01234 111222 | bob@smith.com | | Phone | Bob smith | Bobs Address | 01234 111222 | bob@smith.com | | Email | Bob smith | Bobs Address | 01234 111222 | bob@smith.com | +--------------+-----------+--------------+--------------+---------------+
这显然是不对的。
任何人都可以建议在SQL Server存储过程中如何做到这一点吗?
首先,您的Answers桌子经过精心设计。该表未规范化,当您要返回数据时会给您带来麻烦。如果可能,您需要重组该表。
Answers
如果您不能重新设计表格,那么您将不得不取消对答案表的透视,以便能够轻松地将答案与问题结合起来。
UNPIVOT将获取您的列并将其转换为行。不可更改的代码将是:
select formid, RecordId, answer, answercol from answers a unpivot ( answer for answerCol in ([Answer01], [Answer02], [Answer03], [Answer04], [Answer05], [Answer06]) ) unpiv;
请参阅带有演示的SQL Fiddle。结果如下:
| FORMID | RECORDID | ANSWER | ANSWERCOL | -------------------------------------------------- | 1 | 1 | Bob Smith | Answer01 | | 1 | 1 | Bobs Address | Answer02 | | 1 | 1 | 01234 111222 | Answer03 | | 1 | 1 | bob@smith.com | Answer04 |
数据放入行后,您可以加入问题表以返回所需的结果:
select q.questiontext, d.answer from questions q inner join ( select formid, RecordId, answer, answercol from answers a unpivot ( answer for answerCol in ([Answer01], [Answer02], [Answer03], [Answer04], [Answer05], [Answer06]) ) unpiv ) d on q.AnswerField = d.answercol and q.formid = d.formid where d.recordid = 1;
| QUESTIONTEXT | ANSWER | -------------------------------- | Name | Bob Smith | | Address | Bobs Address | | Phone | 01234 111222 | | Email | bob@smith.com |