Yet*_*ish 3 sql sql-server unpivot
我正在开发一个允许可配置问题和答案的应用程序.目前最多可以有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 |
+----+--------+--------------+-------------+
Run Code Online (Sandbox Code Playgroud)
+----+--------+----------+------------+--------------+--------------+----------------+----------+----------+
| 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 | |
+----+--------+----------+------------+--------------+--------------+----------------+----------+----------+
Run Code Online (Sandbox Code Playgroud)
所以在Questions表中,AnswerField Answer01映射到Answers表中的Answer01列
我想做的是得到一个类似于的结果集:
表格ID 1和记录ID 1:
+--------------+---------------+
| QuestionText | Answer |
+--------------+---------------+
| Name | Bob Smith |
| Address | Bobs Address |
| Phone | 01234 111222 |
| Email | bob@smith.com |
+--------------+---------------+
Run Code Online (Sandbox Code Playgroud)
然后对于表单ID 2和记录ID 3:
+--------------+---------+
| QuestionText | Answer |
+--------------+---------+
| First Name | David |
| Surname | Jones |
+--------------+---------+
Run Code Online (Sandbox Code Playgroud)
我尝试过使用数据透视表:
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
Run Code Online (Sandbox Code Playgroud)
但是这会重复所有列中的答案:
+--------------+-----------+--------------+--------------+---------------+
| 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 |
+--------------+-----------+--------------+--------------+---------------+
Run Code Online (Sandbox Code Playgroud)
这显然是不对的.
任何人都可以建议如何在SQL Server存储过程中完成这项工作吗?
Tar*_*ryn 12
首先,你的Answers桌子设计非常好.该表未规范化,当您想要返回数据时会导致问题.如果可能,您需要重组该表.
如果您无法重新设计表格,则必须取消回答表格,以便能够轻松加入问题的答案.
UNPIVOT将获取您的列并将其转换为行.unpivot代码将是:
select formid, RecordId, answer, answercol
from answers a
unpivot
(
answer
for answerCol in ([Answer01], [Answer02], [Answer03],
[Answer04], [Answer05], [Answer06])
) unpiv;
Run Code Online (Sandbox Code Playgroud)
请参阅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 |
Run Code Online (Sandbox Code Playgroud)
一旦数据在行中,您就可以加入问题表以返回所需的结果:
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;
Run Code Online (Sandbox Code Playgroud)
请参阅SQL Fiddle with Demo.这给出了一个结果:
| QUESTIONTEXT | ANSWER |
--------------------------------
| Name | Bob Smith |
| Address | Bobs Address |
| Phone | 01234 111222 |
| Email | bob@smith.com |
Run Code Online (Sandbox Code Playgroud)