透视动态列,无聚合

Posted

技术标签:

【中文标题】透视动态列,无聚合【英文标题】:Pivot Dynamic Columns, no Aggregation 【发布时间】:2012-08-12 17:19:27 【问题描述】:

我在 SQL Server 2008 中有问卷数据,我想将其转置为矩阵。 我看到了几篇关于同一主题的帖子,但我就是不明白。

给出以下表格:

Question table

Answer table

Customer table

列数:[CustomerID][QuestionName_1]、..、[QuestionName_n] 动态问题列数)数据:CustomerID, Answer_1, .., Answer_n

检索列的代码:

DECLARE @columns VARCHAR(8000)

SELECT @columns = COALESCE(@columns + ',[' + cast(QuestionName as varchar) + ']',
'[' + cast(QuestionName as varchar)+ ']')
FROM Answer A 
INNER JOIN Question Q ON A.QuestionID = Q.QuestionID
INNER JOIN Customer C ON A.CustomerID = C.CustomerID
GROUP BY Q.QuestionName

SET @columns = '[CustomerID],' + @columns

DECLARE @query VARCHAR(8000)
SET @query = 'Some PIVOT query without aggregation'

EXECUTE(@query)

最初的查询思路取自pivots with dynamic columns。

可以做到吗?旋转查询会是什么样子? ps:我不想使用具有最大列数的排名。

问候,

米歇尔

【问题讨论】:

【参考方案1】:

是的,您可以执行动态枢轴。有时,首先使用静态版本来处理 PIVOT 查询会更容易,这样您就可以看到查询和结果的显示方式。然后将查询转换为动态版本。

以下是查询的静态与动态版本的示例:

静态(SQL Fiddle):

select *
from 
(
    select u.userid,
        u.fname,
        u.lname,
        u.mobile,
        r.question,
        r.choice
    from users u
    left join results r
        on u.questionid = r.questionid
        and u.choiceid = r.choiceid
) x
pivot
(
    min(choice)
    for question in([are you], [from])
) p

动态 (SQL Fiddle):

DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

SET @cols = STUFF((SELECT distinct ',' + QUOTENAME(c.question) 
            FROM results c
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT userid, fname, lname, mobile, ' + @cols + ' from 
            (
                select u.userid,
                    u.fname,
                    u.lname,
                    u.mobile,
                    r.question,
                    r.choice
                from users u
                left join results r
                    on u.questionid = r.questionid
                    and u.choiceid = r.choiceid
           ) x
            pivot 
            (
                min(choice)
                for question in (' + @cols + ')
            ) p '


execute(@query)

如果您可以提供有关当前表结构的更多详细信息,然后提供一些示例数据。我们应该能够帮助您创建适合您情况所需的版本。

不过,正如我所说,有时从静态版本开始会更容易,您可以先在需要转换的列中硬编码,然后再转到动态版本。

【讨论】:

在您的示例中,“选择”字段具有什么数据类型?我有一个 varchar 字段,其中包含问题的答案。 这是一个varchar,如果您查看 SQL Fiddle,它将显示表结构。 我已经开始使用 MIN(QuestionName)。我没想到!谢谢你的帮助蓝:)。 非常感谢您的查询,它将在我身边成功执行,但我的问题是如何将列值与 DataReader 或 DataSet 绑定。请告诉我该怎么做。 @Harshal 您需要Ask A new Question 并包括所有相关详细信息,包括您的代码、查询等。

以上是关于透视动态列,无聚合的主要内容,如果未能解决你的问题,请参考以下文章

动态 SQL 透视查询中的分组和聚合函数

透视动态列[重复]

SQL 动态数据透视表列顺序

基于拆分值透视动态列

在 Oracle 中使用动态列进行透视

使用数据透视的动态列