查询特定于数据

时间:2016-10-26 13:10:05

标签: sql-server tsql pivot

我的数据格式如下

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');

请帮我解释如何写下查询

2 个答案:

答案 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)

您将需要Dynamic SQL with a PIVOT

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