SQL行分列(SQL Rows to Columns)

2019-06-17 16:19发布

我有一个表,要转的行列,类似透视表,但没有总结。

例如,我有如下表:

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

主要的要求是,我不知道在设计时该问题的文本将是什么。

请谁能帮 - 我拉我的头发:操作系统

从本质上讲,你能保证会有在这种情况下每个对应的问题的答复。

Answer 1:

你不能做到这一点与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操作上套,列布局是一组的隐含属性。

你应该定义要在设计时得到一组的布局,就像你定义一个varible的数据类型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')

详情请参见我的博客此项:

  • 动态透视


Answer 2:

做你的分组和汇总首先,使用Quassnoi的答案作为中间结果。

当你不再会做的结果组面向operatons交叉表,只应做。 一些SQL方言有像PIVOT关键字,变换或交叉制表做到这一点,但你可能会更好过使用XSLT。



文章来源: SQL Rows to Columns