0

使用 STUFF 函数执行 SQL Pivot 动态列但没有得到我想要的结果

这是 SQL Fiddle http://sqlfiddle.com/#!3/241c2/6/0

我能做些什么来摆脱所有的 null\empty 单元格?

我希望结果显示是这样的,其中每列显示每个学生分配到的班级列表,而没有一堆空白单元格

汤姆哈里玛丽苏保罗
代数 代数 代数 代数 几何
法国 法国 西班牙 西班牙 艺术
生物学 物理学 物理学 生物学

编辑:请求在此处显示代码:

create table clsassin

(

    ClassID int,

    AssignID int,

    ClsNm varchar(10),

    StudntNm varchar(10),

)



insert into clsassin values (1, 1, 'Algebra', 'Tom')

insert into clsassin values (1, 2, 'Algebra', 'Harry')

insert into clsassin values (1, 3, 'Algebra', 'Mary')

insert into clsassin values (1, 4, 'Algebra', 'Sue')

insert into clsassin values (2, 5, 'Geometry', 'Paul')

insert into clsassin values (3, 6, 'French', 'Harry')

insert into clsassin values (3, 7, 'French', 'Tom')

insert into clsassin values (4, 8, 'Spanish', 'Mary')

insert into clsassin values (4, 9, 'Spanish', 'Sue')

insert into clsassin values (5, 10, 'Art', 'Paul')

insert into clsassin values (6, 11, 'Biology', 'Tom')

insert into clsassin values (6, 12, 'Biology', 'Paul')

insert into clsassin values (7, 13, 'Physics', 'Harry')

insert into clsassin values (7, 14, 'Physics', 'Sue')

insert into clsassin values (8, 15, 'History', 'Sue')

DECLARE @cols AS NVARCHAR(MAX),

    @query  AS NVARCHAR(MAX)



select @cols = STUFF((SELECT distinct ',' + QUOTENAME(StudntNm) 
                  FROM clsassin 

FOR XML PATH(''), TYPE

).value('.', 'NVARCHAR(MAX)') 

,1,1,'')



set @query = 'SELECT ' + @cols + ' from 

    (

        select StudntNm, ClsNm
, ClassID                
        from clsassin

    ) x

    pivot 

    (

        min(ClsNm)

        for StudntNm in (' + @cols + ')

    ) p '



execute(@query)
4

2 回答 2

4

原始查询的问题是您将 包含classidselectPIVOT 的数据列表中。您有 8 个不同的classid值,然后在枢轴中应用聚合函数时将按这些值进行分组。

问题是,如果您排除 classid 并应用数据透视表,您将只返回每个学生的一个值 - 与min(ClsNm)

由于您想显示每个学生的每个班级,那么您应该考虑使用row_number()窗口函数而不是 classid。如果您按 应用row_number()和分区数据studntNm,那么您将为每个学生的每个班级分配一个递增的数字,然后当您聚合数据时,您将返回每一行。

代码将是:

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

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(StudntNm) 
                  FROM clsassin 
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT ' + @cols + ' 
            from 
            (
                select StudntNm, ClsNm,
                  row_number() over(partition by StudntNm
                                      order by ClsNm) rn
                from clsassin
            ) x
            pivot 
            (
                min(ClsNm)
                for StudntNm in (' + @cols + ')
            ) p '

execute sp_executesql @query;

请参阅SQL Fiddle with Demo。这会给你结果:

|   HARRY |    MARY |     PAUL |     SUE |     TOM |
----------------------------------------------------
| Algebra | Algebra |      Art | Algebra | Algebra |
|  French | Spanish |  Biology | History | Biology |
| Physics |  (null) | Geometry | Physics |  French |
|  (null) |  (null) |   (null) | Spanish |  (null) |
于 2013-07-21T13:10:20.897 回答
0

我已使用此方法显示销售汇总表,例如:

产品,Jan2013,Feb2013,.....

使用 FOR XML PATH('') 方法返回所有月份,但它们没有排序。我可以按照正确的顺序对它们进行排序吗?我在下面附上了我的代码:

SET @cols = STUFF((SELECT distinct ',' + '[' + DATENAME(month,DateTime) + DATENAME(year,DateTime) +']' AS MonthYear 
                from DRGCase dc INNER JOIN Company c ON dc.HospitalId=c.CompanyId 
                WHERE dc.DischargeDate > @StartDate AND dc.DischargeDate <= DATEADD(DAY,1,@Enddate)
                FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'),1,1,'');

SELECT @query='SELECT Hospital,' + @cols + 
    'FROM
    (
    SELECT c.CompanyName AS Hospital, DATENAME(month,DateTime) + DATENAME(year,DateTime) AS MonthYear,COUNT(*) AS Cases 

    FROM DRGCase dc INNER JOIN Company c ON dc.HospitalId=c.CompanyId 

    WHERE dc.DischargeDate > ''' + CONVERT(CHAR(10),@StartDate,126) + ''' AND dc.DischargeDate <= DATEADD(DAY,1,''' + CONVERT(CHAR(10),@EndDate,126) + ''')

    GROUP BY c.CompanyName, DATENAME(month,DateTime) + DATENAME(year,DateTime)
    ) ps PIVOT
    (
        sum(Cases)
        FOR MonthYear IN (' + @cols + ')
    )
    as pvt'
exec(@query)
于 2015-02-17T10:29:10.367 回答