当您将数据从行转移到列时,有几种方法可以执行此操作。你可以在CASE表达式中使用聚合函数,或者因为你使用的是SQL Server,你可以使用PIVOT函数。在这两种情况下,你都会应用某种聚合。
由于您只是想显示ratings
和name
,如果将聚合函数应用于字符串列,那么在使用GROUP BY
时将返回一行。
使用聚合函数的情况进行的语法:
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生成应用组时需要的唯一值。
您也可以使用旋转功能时使用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
感谢您的答复先生。 你刚才在select语句中提到了“Lunch”和“Dinner”作为硬编码。但是我可以在该表中插入更多记录tbl_createria.I需要选择并显示我已插入tbl_creteria中作为列的记录。希望这是明确的先生。请让我知道如果这不是。 – user2003780
@ user2003780查看我的编辑,如果值未知,您将不得不使用动态sql来获取结果。 – Taryn