我有一个名为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
希望这很清楚。如果不是,请告诉我。
答案 0 :(得分:0)
当您将数据从行转换为列时,有几种方法可以执行此操作。您可以将聚合函数与CASE表达式一起使用,或者由于您使用的是SQL Server,因此可以使用PIVOT函数。在这两种情况下,您将使用group by应用某种聚合。
由于您只想显示ratings
和name
,如果将聚合函数应用于字符串列,则在使用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)