将表中的记录显示为SQL Server中的列

时间:2013-06-03 08:58:06

标签: sql sql-server-2008 pivot

我有一个名为tbl_Criteria的表格,此处可用的列是ID,名称 和样本记录在下面给出

D        Name
1        Lunch
2        Dinner

我正在使用另一个名为tbl_Feedback的表,其中包含以下列的列

ID      UserID    Creteria      Ratings
1        129         2            A
2        329         2            B
3        520         1            C

我的需要是我需要将列表作为专栏显示,我需要给出评级 如下所示

Dinner  Lunch
A       C
B       Null

希望这很清楚。如果不是,请告诉我。

1 个答案:

答案 0 :(得分:0)

当您将数据从行转换为列时,有几种方法可以执行此操作。您可以将聚合函数与CASE表达式一起使用,或者由于您使用的是SQL Server,因此可以使用PIVOT函数。在这两种情况下,您将使用group by应用某种聚合。

由于您只想显示ratingsname,如果将聚合函数应用于字符串列,则在使用GROUP BY时将返回一行。

使用带有CASE的聚合函数的语法将是:

select 
  max(case when name = 'Dinner' then ratings end) Dinner,
  max(case when name = 'Lunch' then ratings end) Lunch
from tbl_feedback f
inner join tbl_criteria c
  on f.creteria = c.d;

SQL Fiddle with Demo。但是如果你运行上面的查询,你只会返回一行:

| DINNER | LUNCH |
------------------
|      B |     C |

因此,您需要包含一些值,以允许在最终结果中包含不同的行。由于您使用的是SQL Server,因此可以应用row_number()。如果您添加row_number(),则可以creteria对数据进行分区,类似于以下内容:

select 
  max(case when name = 'Dinner' then ratings end) Dinner,
  max(case when name = 'Lunch' then ratings end) Lunch
from
(
  select f.ratings, c.name, 
    row_number() over(partition by f.creteria order by f.id) rn
  from tbl_feedback f
  inner join tbl_criteria c
    on f.creteria = c.d
) d
group by rn;

SQL Fiddle with Demo。 row_number生成应用group by时所需的唯一值。

使用PIVOT功能时,您也可以使用row_number()

select dinner, lunch
from
(
  select f.ratings, c.name, 
    row_number() over(partition by f.creteria order by f.id) rn
  from tbl_feedback f
  inner join tbl_criteria c
    on f.creteria = c.d
) d
pivot
(
  max(ratings)
  for name in (dinner, lunch)
) piv;

SQL Fiddle with Demo。这些查询的最终结果将是:

| DINNER |  LUNCH |
-------------------
|      A |      C |
|      B | (null) |

编辑#1:如果您有未知或动态数量的条件名称,则需要使用动态sql来生成结果。

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

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(name) 
                    from tbl_Criteria
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT ' + @cols + ' 
            from 
             (
                select f.ratings, c.name, 
                  row_number() over(partition by f.creteria order by f.id) rn
                from tbl_feedback f
                inner join tbl_criteria c
                  on f.creteria = c.d
            ) d
            pivot 
            (
                max(ratings)
                for name in (' + @cols + ')
            ) p '

execute(@query)

请参阅SQL Fiddle with Demo