我有一张看起来像这样的桌子:
日期 | 姓名 | 实际 | 目标 |
---|---|---|---|
2023-03-14 | 鲍勃 | 15 | 15 |
2023-03-14 | 吉姆 | 9 | 5 |
2023-03-14 | 史蒂夫 | 10 | 9 |
2023-03-15 | 鲍勃 | 11 | 11 |
2023-03-15 | 吉姆 | 16 | 16 |
2023-03-15 | 史蒂夫 | 5 | 12 |
名称列并不总是相同,具体取决于谁在工作,因此枢轴必须是动态的。 我希望表格看起来像这样:
日期 | 鲍勃_实际 | 鲍勃_目标 | 吉姆_实际 | 吉姆_目标 | 史蒂夫_实际 | 史蒂夫_目标 |
---|---|---|---|---|---|---|
2023-03-14 | 15 | 15 | 9 | 5 | 10 | 9 |
2023-03-15 | 11 | 11 | 16 | 16 | 5 | 12 |
如果我只是动态地围绕目标旋转,我就能够获得所需的结果,但我不知道如何同时旋转目标和实际
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT ',' + QUOTENAME(Name)
from yt
group by Name
order by Name
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT Date,' + @cols + ' from
(
select Date, Name, Target
from yt
) x
pivot
(
sum(Target)
for Name in (' + @cols + ')
) p '
execute(@query);
我使用上面的代码让它只适用于目标,但不知道如何添加实际的
不要使用枢轴,它们不够灵活,尝试条件聚合:
SELECT *
INTO #yt
FROM (
VALUES (N'2023-03-14', N'Bob', 15, 15)
, (N'2023-03-14', N'Jim', 9, 5)
, (N'2023-03-14', N'Steve', 10, 9)
, (N'2023-03-15', N'Bob', 11, 11)
, (N'2023-03-15', N'Jim', 16, 16)
, (N'2023-03-15', N'Steve', 5, 12)
) t (Date,Name,Actual,Target)
DECLARE @cols AS NVARCHAR(MAX)
, @query AS NVARCHAR(MAX)
SELECT @cols = (
SELECT '
, SUM(case when name = ' + QUOTENAME(Name, '''') + ' then Actual END) AS ' + QUOTENAME(Name + '_Actual') + N'
, SUM(case when name = ' + QUOTENAME(Name, '''') + ' then Target END) AS ' + QUOTENAME(Name + '_Targer')
FROM #yt
GROUP BY Name
ORDER BY Name
FOR XML PATH(''), TYPE
).value('text()[1]', 'NVARCHAR(MAX)')
SET @query = '
SELECT Date' + @cols + '
FROM #yt
GROUP BY Date
'
EXEC(@query);
这样,您可以更灵活地处理列名称和值。 SUM(CASE WHEN ...) 是条件聚合部分,用于获取所需的值并将它们放置在正确的列中。