SQL 相关矩阵

SQL Correlation Matrix

我在 MS SQL 服务器中有一个数据表 如下所示

date    time    strategy    PL
20150505    1135    402016  -53
20150507    1410    291821  -31
20150520    1535    251209  -17
20150619    940 281316  49
20160302    1020    471105  -7
20160421    1515    221908  -9
20190520    1145    150711  -10
20171229    1100    252111  0
20180424    1355    401720  -10
20180516    1005    312913  15
20180605    1145    220711  -5
20181019    1450    250724  18
20190211    1050    282710  -19
20160425    1100    451105  22
20160816    1110    421116  -8
20160915    1505    383106  -21
20171114    1355    453922  16
20171116    930 422805  -7
20171129    1010    463216  -4
20160801    1345    141208  -7
20160912    935 211814  91
20170627    1310    470714  -8
20170803    1615    381024  0
20170825    1310    431012  -1
20171114    1020    383614  -14
20190523    1000    262409  3
20190815    940 431616  -6
20191230    1035    291607  -2
20200221    1555    483216  -9
20171124    1625    301613  8
20180824    1305    402124  -19
20181003    1410    402725  11
20181016    1135    220907  23
20190102    1020    463422  -8
20190118    935 463610  12
20150511    1105    382023  -41
20151218    950 481012  -15
20160708    1500    321518  20
20160712    1550    341712  -6
20161024    1110    100825  -36
20170308    1050    462413  0
20180808    1300    423611  -16
20180904    1115    381120  3
20190906    1500    380817  -9
20191205    1425    341509  -5
20200103    930 491222  -16
20150223    1430    211014  -18
20151027    1350    451711  23

我想创建时间 1 的所有策略和时间 2 的所有策略之间的相关系数矩阵,如下所示(横轴为时间 1,纵轴为时间 2)

      402016    402017   402018   402019 ... ... ... 
402016    0.1     0.3     0.7       0.5
402017    0.4      0.7     0.9       0.432 
402018   0.22      -0.2    -0.477    -0.56 
402019   -0.5      -0.7     0.6      0.8
'''

这是我的代码。由于 Table 太大而无法使用数据透视表。我将结果插入 table

IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[fnGetCorrelation1]') )
  DROP FUNCTION [dbo].[fnGetCorrelation1]
GO


CREATE FUNCTION [dbo].[fnGetCorrelation1]
                        (
                        @Strategy1 VARCHAR(10),
                        @Strategy2 VARCHAR(10),
                        @Time1 VARCHAR(10),
                        @Time2 VARCHAR(10)
                        )
                        RETURNS FLOAT
AS

BEGIN
                    DECLARE     @Corr FLOAT
                        
                    SELECT
                            @Corr =  (AVG(([Strategy1])*([Strategy2])))/(STDEVP([Strategy1])*STDEVP([Strategy2]))
                                  FROM 
              
                                  (SELECT [Date] , isnull([Stratgy1],0) as  [Strategy1] , isnull([Stratgy2],0) as [Strategy2] FROM 
                                        (SELECT 
                                     [Date],
                                     
                                    CASE WHEN [Strategy] + [time] * 1000000 = @Strategy1 + @time1 * 1000000 THEN 'Stratgy1' ELSE 'Stratgy2'END AS [Strategy], 
                                     [PL] 
                                      FROM [**].[dbo].[grouppedResult]
                                      WHERE ([time] = @time1 or [time] = @time2) AND ([Strategy] = @Strategy1 OR [Strategy] = @Strategy2)) as SourceTable 
  
                                      PIVOT

                                      (SUM([PL]) FOR [Strategy] in ( [Stratgy1], [Stratgy2])) as PivotTable 
                                  ) Datatable



          RETURN(@Corr) 

END
GO
/*############################################################*/
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[uspGetCorrMatrix]') AND type in (N'P', N'PC'))
  DROP PROCEDURE [dbo].[uspGetCorrMatrix]
GO
CREATE PROC [dbo].[uspGetCorrMatrix] 
  
  @time1 INT, 
  @time2 INT
AS
BEGIN
    DECLARE @Sql NVARCHAR(MAX)
    DECLARE @ColumnsText NVARCHAR(MAX)
    DECLARE @StrategyList TABLE (Strategy INT)

    INSERT INTO @StrategyList SELECT  [strategy]   FROM [**].[dbo].[grouppedResult] WHERE [time] = @time1 or [time] = @time2  GROUP BY [strategy]  ORDER BY [strategy] 

    /*SELECT * FROM @StrategyList*/

    SELECT @ColumnsText = COALESCE(@ColumnsText + ',','') + QUOTENAME([strategy])  FROM   @StrategyList AS Columns  ORDER BY Columns.[strategy] 
    
    
     INSERT INTO [**].[dbo].[correlation] select [Strategy1] = a.[strategy], [Strategy2] = b.[strategy] , [Time1] = @time1 , [Time2] = @time2,
    [Corr] =  dbo.fnGetCorrelation1(a.[strategy], b.[strategy], CONVERT(varchar(4), @time1), CONVERT(varchar(4), @time2))
    from @StrategyList a CROSS JOIN @StrategyList b
    
END 
GO

EXEC [dbo].[uspGetCorrMatrix] '930', '935'