Tsql While循环为pivot添加数据

Tsql While循环为pivot添加数据,tsql,while-loop,pivot,pivot-table,Tsql,While Loop,Pivot,Pivot Table,目前,我有一个要求,需要一个如下所示的表格: Instrument Long Short 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 .... Fixed 41 41 35 35 35 35 35 35 35 53 25 25 Index 16 16 22 22 22 32 1

目前,我有一个要求,需要一个如下所示的表格:

Instrument  Long  Short  2013  2014  2015  2016  2017  2018  2019   2020  2021  2022 ....    
Fixed       41    41     35    35    35    35    35    35    35     53    25    25
Index       16    16     22    22    22    32    12    12    12     12    12    12
Credits     29    29     41    16    16    16    16    16    16     16    16    16
Short term  12    12     5     5     5     5     5     5     5      5     5     17
SET @columnlist = STUFF(
  (
    SELECT  ', [' + CAST(Number) + ']'
    FROM numbers
    WHERE Number BETWEEN YEAR(GETDATE())
                     AND (SELECT YEAR(MAX(MaturityDate)) FROM YourTable)
    ORDER BY Number
  FOR XML PATH ('')
  ),
  1, 2, ''
);
我的工作台如下所示:

Instrument  Long  Short  Annual Coupon  Maturity Date  Instrument ID
Fixed       10    10     10             01/01/2025     1   
Index       5     5      10             10/05/2016     2
Credits     15    15     16             25/06/2020     3
Short term  12    12     5              31/10/2022     4
Fixed       13    13     15             31/03/2030     5
Fixed       18    18     10             31/01/2019     6
Credits     14    14     11             31/12/2013     7
Index       11    11     12             31/10/2040     8
..... etc
因此,基本上,轴心中的多头和空头应该是每个不同的工具ID的总和。然后,对于每一年,我需要计算每个年息的总和,直到到期日,其中多头和息票率相加


我的想法是,我必须创建一个while循环,该循环将在一个表中填充每个工具的每年记录,直到到期日为止,这样我就可以使用sql透视进行透视。这看起来可行吗?关于最佳方法的其他想法,尤其是我可能需要while循环的帮助吗?

以下解决方案使用数字表展开表中的范围,对展开集中的某些数据列执行一些特殊处理,并最终旋转结果:

WITH unfolded AS (
  SELECT
    t.Instrument,
    Long      = SUM(z.Long ) OVER (PARTITION BY Instrument),
    Short     = SUM(z.Short) OVER (PARTITION BY Instrument),
    Year      = y.Number,
    YearValue = t.AnnualCoupon + z.Long + z.Short
  FROM YourTable t
  CROSS APPLY (SELECT YEAR(t.MaturityDate)) x (Year)
  INNER JOIN numbers y ON y.Number BETWEEN YEAR(GETDATE()) AND x.Year
  CROSS APPLY (
    SELECT
      Long  = CASE y.Number WHEN x.Year THEN t.Long  ELSE 0 END,
      Short = CASE y.Number WHEN x.Year THEN t.Short ELSE 0 END
  ) z (Long, Short)
),
pivoted AS (
  SELECT *
  FROM unfolded
  PIVOT (
    SUM(YearValue) FOR Year IN ([2013], [2014], [2015], [2016], [2017], [2018], [2019], [2020],
                [2021], [2022], [2023], [2024], [2025], [2026], [2027], [2028], [2029], [2030],
                [2031], [2032], [2033], [2034], [2035], [2036], [2037], [2038], [2039], [2040])
  ) p
)
SELECT *
FROM pivoted
;
它返回静态范围为年的结果。要将其用于动态计算的年份范围,首先需要将年份列表准备为CSV字符串,如下所示:

Instrument  Long  Short  2013  2014  2015  2016  2017  2018  2019   2020  2021  2022 ....    
Fixed       41    41     35    35    35    35    35    35    35     53    25    25
Index       16    16     22    22    22    32    12    12    12     12    12    12
Credits     29    29     41    16    16    16    16    16    16     16    16    16
Short term  12    12     5     5     5     5     5     5     5      5     5     17
SET @columnlist = STUFF(
  (
    SELECT  ', [' + CAST(Number) + ']'
    FROM numbers
    WHERE Number BETWEEN YEAR(GETDATE())
                     AND (SELECT YEAR(MAX(MaturityDate)) FROM YourTable)
    ORDER BY Number
  FOR XML PATH ('')
  ),
  1, 2, ''
);
然后将其放入查询的动态SQL版本中:

SET @sql = N'
WITH unfolded AS (
...
  PIVOT (
    SUM(YearValue) FOR Year IN (' + @columnlist + ')
  ) p
)
SELECT *
FROM pivoted;
';
并执行结果:

EXECUTE(@sql);

您可以尝试此解决方案。

您能解释一下所需结果中的
/
总计背后的逻辑吗?为什么
2016
for
Fixed
的值为
110
?长短只是每个工具报告期的值。上面的两个表使用的数据不一样,我只是随机编出来的。你能编辑期望的结果使其与你的样本数据相匹配吗?如果数据/结果不匹配,则很难确定逻辑。抱歉,我现在已编辑