ITh*_*wer 1 sql-server pivot crosstab
我有一个表,并希望将其行转置为列,类似于数据透视表但没有汇总.
例如,我有以下表格:
Question
--QuestionID
--QuestionText
Response
--ResponseID
--ResponseText
--QuestionID
Run Code Online (Sandbox Code Playgroud)
基本上我希望能够创建一个动态表,如:
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
Run Code Online (Sandbox Code Playgroud)
主要要求是我在设计时不知道问题文本是什么.
请有人帮忙 - 我把头发拉出来:oS
基本上,您可以保证在此方案中每个相应问题都会有响应.
SQL
除非您知道设计时间中的列数(即问题),否则您无法使用(动态查询除外).
您应该以表格格式提取所需数据,然后在客户端处理它:
SELECT *
FROM Question
LEFT OUTER JOIN
Response
ON Response.QuestionId = Question.QuestionID
Run Code Online (Sandbox Code Playgroud)
或者,可能是这个(在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
Run Code Online (Sandbox Code Playgroud)
后一个查询将以这种形式给出结果(如果您有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
Run Code Online (Sandbox Code Playgroud)
,这是它将以表格形式输出数据,并rn
标记行号.
每当您rn
在客户端上看到更改时,您只需关闭<tr>
并打开新客户端.
您可以安全地为<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')
Run Code Online (Sandbox Code Playgroud)
有关详细信息,请参阅我的博客中的此条目:
归档时间: |
|
查看次数: |
14110 次 |
最近记录: |