我正在开发一个允许可配置问题和答案的应用程序。目前最多可以有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 | |
+----+--------+----------+------------+--------------+--------------+----------------+----------+----------+
所以在问题表中,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&记录身份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存储过程中完成此操作吗?
答案 0 :(得分:12)
首先,您的Answers
表格设计得非常好。该表未规范化,当您想要返回数据时会导致问题。如果可能,您需要重组该表。
如果您无法重新设计表格,则必须取消回答表格,以便能够轻松加入问题的答案。
UNPIVOT将获取您的列并将其转换为行。 unpivot代码将是:
select formid, RecordId, answer, answercol
from answers a
unpivot
(
answer
for answerCol in ([Answer01], [Answer02], [Answer03],
[Answer04], [Answer05], [Answer06])
) unpiv;
见SQL Fiddle with Demo。这给出了一个结果:
| 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;
见SQL Fiddle with Demo。这给出了一个结果:
| QUESTIONTEXT | ANSWER |
--------------------------------
| Name | Bob Smith |
| Address | Bobs Address |
| Phone | 01234 111222 |
| Email | bob@smith.com |