我的数据格式如下
ITEMNO Fes Year Funds
1938331 LF 2016 334
1938331 LF 2016 123
1938331 LF 2017 234
1938331 SL 2016 099
1938331 SL 2017 080
1938331 SL 2017 741
1938331 SL 2018 41
我希望我的输出格式如下
ITEMNO FES S(2016) S(2017) S(2018)
1938331 LF 334+123 234 0
1938331 SL 099 080+741 41
这是样本数据设置:
CREATE TABLE mytable(
ITEMNO INTEGER NOT NULL
,Fes VARCHAR(2) NOT NULL
,Year INTEGER NOT NULL
,Funds VARCHAR(3) NOT NULL
);
INSERT INTO mytable(ITEMNO,Fes,Year,Funds) VALUES (1938331,'LF',2016,'334');
INSERT INTO mytable(ITEMNO,Fes,Year,Funds) VALUES (1938331,'LF',2016,'123');
INSERT INTO mytable(ITEMNO,Fes,Year,Funds) VALUES (1938331,'LF',2017,'234');
INSERT INTO mytable(ITEMNO,Fes,Year,Funds) VALUES (1938331,'SL',2016,'099');
INSERT INTO mytable(ITEMNO,Fes,Year,Funds) VALUES (1938331,'SL',2017,'080');
INSERT INTO mytable(ITEMNO,Fes,Year,Funds) VALUES (1938331,'SL',2017,'741');
INSERT INTO mytable(ITEMNO,Fes,Year,Funds) VALUES (1938331,'SL',2018,'41');
请帮我解释如何写下查询
答案 0 :(得分:1)
以下内容将动态地(即,源表中显示的任意年份)为您提供预期结果。你会看到要做到这一点,你需要相当多的复杂结构。这就是为什么人们经常说(有正确的)T-SQL不是正确的语言。但是如果你真的需要在T-SQL中这样做,那么:
CREATE TABLE #mytable(
ITEMNO INTEGER NOT NULL
,Fes VARCHAR(2) NOT NULL
,Year INTEGER NOT NULL
,Funds INTEGER NOT NULL
);
INSERT INTO #mytable(ITEMNO,Fes,Year,Funds) VALUES (1938331,'LF',2016,'334');
INSERT INTO #mytable(ITEMNO,Fes,Year,Funds) VALUES (1938331,'LF',2016,'123');
INSERT INTO #mytable(ITEMNO,Fes,Year,Funds) VALUES (1938331,'LF',2017,'234');
INSERT INTO #mytable(ITEMNO,Fes,Year,Funds) VALUES (1938331,'SL',2016,'099');
INSERT INTO #mytable(ITEMNO,Fes,Year,Funds) VALUES (1938331,'SL',2017,'080');
INSERT INTO #mytable(ITEMNO,Fes,Year,Funds) VALUES (1938331,'SL',2017,'741');
INSERT INTO #mytable(ITEMNO,Fes,Year,Funds) VALUES (1938331,'SL',2018,'41');
DECLARE @piv_cols NVARCHAR(MAX)=STUFF((
SELECT DISTINCT ',[S('+CAST(year AS VARCHAR)+')]'
FROM #mytable
FOR XML PATH('')
),1,1,'');
DECLARE @sel_cols NVARCHAR(MAX)=STUFF((
SELECT DISTINCT ',[S('+CAST(year AS VARCHAR)+')]=ISNULL([S('+CAST(year AS VARCHAR)+')],''0'')'
FROM #mytable
FOR XML PATH('')
),1,1,'');
DECLARE @sql NVARCHAR(MAX)=N'
SELECT
p.itemno,p.fes,'+@sel_cols+N'
FROM
(
SELECT
ITEMNO,
fes,
q_year=''S(''+CAST(year AS VARCHAR)+'')'',
Funds
FROM
#mytable
) AS bt
PIVOT(
SUM(Funds) FOR q_year IN ('+@piv_cols+')
) AS p
';
EXECUTE (@sql);
DROP TABLE #mytable;
结果是:
╔═════════╦═════╦═════════╦═════════╦═════════╗
║ itemno ║ fes ║ S(2016) ║ S(2017) ║ S(2018) ║
╠═════════╬═════╬═════════╬═════════╬═════════╣
║ 1938331 ║ LF ║ 457 ║ 234 ║ 0 ║
║ 1938331 ║ SL ║ 99 ║ 821 ║ 41 ║
╚═════════╩═════╩═════════╩═════════╩═════════╝
答案 1 :(得分:1)
DECLARE @DynamicPivotQuery AS NVARCHAR(MAX)
DECLARE @ColumnName AS NVARCHAR(MAX)
--Get distinct values of the PIVOT Column
SELECT @ColumnName= ISNULL(@ColumnName + ',','')
+ QUOTENAME([Year])
FROM (SELECT DISTINCT [Year] FROM mytable) AS [Year]
--Prepare the PIVOT query using the dynamic
SET @DynamicPivotQuery =
N'SELECT ITEMNO, Fes, ' + @ColumnName + '
FROM mytable
PIVOT(SUM(cast(Funds as int))
FOR [Year] IN (' + @ColumnName + ')) AS PVTTable'
--Execute the Dynamic Pivot Query
EXEC sp_executesql @DynamicPivotQuery