PIVOT后的列名无效

时间:2014-10-03 15:05:56

标签: sql sql-server-2008 pivot

我想要这样的事情:

42 | 41 | 31 |  32 | Name
----------------------------    
 O                    42  
     X                41  
                P     32  
     Y                41  
     Z                41  

旋转的列标题也是名称列中的值。各列可以具有不同的状态。这就是我所拥有的,但我一直收到错误消息,指出ValveGroupName列无效。

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

select @cols = stuff((select ',' + quotename(ValveGroupName)
                        from dbo.adm_ValveGroup vgroup,
                             dbo.adm_Station station
                       where station.StationID = vgroup.StationID
                         and station.StationName in ('CBRN') 
                       order by vgroup.ValveGroupName desc
                         for xml path(''), type).value('.', 'nvarchar(max)'), 1, 1, '')

set @query = 'select ValveGroupName,' + @cols + ' from
              (
                select vlog.status,
                       vgroup.ValveGroupName                   
                  from dbo.adm_Station station,
                       dbo.adm_ValveGroup vgroup,
                       dbo.valvegroup_log vlog
                 where station.StationID = vgroup.StationID
                   and vgroup.ValveGroupID = vlog.ValveGroupID
                   and station.StationName in (''CBRN'')
                   and vlog.logdate between ''2012-10-01'' and ''2012-10-30''
              ) x
              pivot
              (
                 max(status)
                 for ValveGroupName in (' + @cols + ')
              ) p '

execute (@query)

此查询有什么问题?

1 个答案:

答案 0 :(得分:1)

由于您的ValveGroupName正在成为PIVOT的新列名,因此您通常不会在最终选择列表中包含该列名。由于您基本上是“删除”ValveGroupName以成为新列,因此SQL Server不再具有该列,因此会引发错误。

代码通常是:

set @query = 'select ' + @cols + ' 
          from
          (
            select vlog.status,
                   vgroup.ValveGroupName                   
              from dbo.adm_Station station
              inner join dbo.adm_ValveGroup vgroup
                 on vgroup.ValveGroupID = vlog.ValveGroupID
              inner join dbo.valvegroup_log vlog
                 on station.StationID = vgroup.StationID
             where station.StationName in (''CBRN'')
               and vlog.logdate between ''2012-10-01'' and ''2012-10-30''
          ) x
          pivot
          (
             max(status)
             for ValveGroupName in (' + @cols + ')
          ) p '

但是,由于您要汇总一个字符串,该字符串将为每个ValveGroupName返回一行,如果您想要返回多行,那么您需要包含row_number

set @query = 'select ' + @cols + ' 
          from
          (
            select vlog.status,
                   vgroup.ValveGroupName,
                   seq = row_number() over(partition by vgroup.ValveGroupName               
                                             order by vlog.status)
              from dbo.adm_Station station,
              inner join dbo.adm_ValveGroup vgroup
                 on vgroup.ValveGroupID = vlog.ValveGroupID
              inner join dbo.valvegroup_log vlog
                 on station.StationID = vgroup.StationID
             where station.StationName in (''CBRN'')
               and vlog.logdate between ''2012-10-01'' and ''2012-10-30''
          ) x
          pivot
          (
             max(status)
             for ValveGroupName in (' + @cols + ')
          ) p '

此更改将允许您在每列中返回多行。注意:我还将代码更改为使用INNER JOIN语法而不是逗号连接,并使用WHERE子句中的条件。