我有一个表,想要将其行转置为列,类似于数据透视表但没有汇总。
例如,我有以下表格:
Question
--QuestionID
--QuestionText
Response
--ResponseID
--ResponseText
--QuestionID
基本上我希望能够创建一个类似于:
的动态表Question 1 Text | Question 2 Text | Question 3 Text
---------------------------------------------------
Response 1.1 Text | Response Text 1.2 | Response 1.3
Response 2.1 Text | Response Text 2.2 | Response 2.3
Response 3.1 Text | Response Text 3.2 | Response 3.3
Response 4.1 Text | Response Text 4.2 | Response 4.3
主要要求是我在设计时不知道问题文本是什么。
请有人帮忙 - 我正在拔头发:oS
基本上,您可以保证在此方案中每个相应问题都会有响应。
答案 0 :(得分:7)
除非您知道设计时间内的列数(即问题),否则您无法使用SQL
(动态查询除外)。
您应该以表格格式提取所需数据,然后在客户端进行处理:
SELECT *
FROM Question
LEFT OUTER JOIN
Response
ON Response.QuestionId = Question.QuestionID
或者,可能是这个(SQL Server 2005+
,Oracle 8i+
和PostgreSQL 8.4+
):
SELECT *
FROM (
SELECT q.*, ROW_NUMBER() OVER (ORDER BY questionID) AS rn
FROM Question q
) q
LEFT OUTER JOIN
(
SELECT r.*, ROW_NUMBER() OVER (PARTITION BY questionID ORDER BY ResponseID) AS rn
FROM Response r
) r
ON r.QuestionId = q.QuestionID
AND q.rn = r.rn
ORDER BY
q.rn, q.QuestionID
后一个查询会以这种形式为您提供结果(前提是您有4
个问题):
rn question response
--- --- ---
1 Question 1 Response 1.1
1 Question 2 Response 2.1
1 Question 3 Response 3.1
1 Question 4 Response 4.1
2 Question 1 Response 1.2
2 Question 2 Response 2.2
2 Question 3 NULL
2 Question 4 Response 4.2
3 Question 1 NULL
3 Question 2 NULL
3 Question 3 Response 3.3
3 Question 4 NULL
,这是以表格形式输出数据,rn
标记行号。
每当您在客户端上看到rn
更改时,您只需关闭<tr>
并打开新的。{/ p>
您可以安全地将<td>
的每个结果集行放一个,因为每个rn
确保返回相同的数字或行
这是一个经常被问到的问题。
SQL
只是不是使用动态列数返回数据的正确工具。
SQL
对集合进行操作,列布局是集合的隐式属性。
您应该在设计时定义要获取的集合的布局,就像在C
中定义变量的数据类型一样。
C
适用于严格定义的变量,SQL
适用于严格定义的集合。
请注意,我并不是说这是最好的方法。这就是SQL
的工作方式。
<强>更新强>
在SQL Server
中,您可以将HTML
表格从数据库中拉出来:
WITH a AS
(
SELECT a.*, ROW_NUMBER() OVER (PARTITION BY question_id ORDER BY id) AS rn
FROM answer a
),
rows AS (
SELECT ROW_NUMBER() OVER (ORDER BY id) AS rn
FROM answer a
WHERE question_id =
(
SELECT TOP 1 question_id
FROM answer a
GROUP BY
question_id
ORDER BY
COUNT(*) DESC
)
)
SELECT (
SELECT COALESCE(a.value, '')
FROM question q
LEFT JOIN
a
ON a.rn = rows.rn
AND a.question_id = q.id
FOR XML PATH ('td'), TYPE
) AS tr
FROM rows
FOR XML PATH(''), ROOT('table')
有关详细信息,请参阅我的博客中的此条目:
答案 1 :(得分:0)
首先使用Quassnoi的答案作为中间结果进行分组和聚合。
只有当您不再对结果进行面向集合的操作时,才应该进行交叉制表。一些SQL方言有像PIVOT,TRANSFORM或CROSSTABULATE这样的关键字来实现这一点,但你最好还是使用XSLT。