2014-10-03 158 views
0

后,我想是这样的:无效的列名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

由于您的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,如果要返回多行,那么你就需要包括a 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子句中的条件。

+0

谢谢。如果我没有进行任何左或右连接,为什么内连接而不是连接comman? – KrisW 2014-10-03 16:34:58

+0

@KrisW逗号语法是INNER JOIN。我将它改为该语法,因为这是SQL的当前标准。 – Taryn 2014-10-03 17:05:43