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>
并打开新的。
您可以安全地<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')
有关更多详细信息,请参阅我的博客中的此条目: