2012-10-01 95 views
1

相关矩阵,我试图让SQL Server中的相关矩阵和我的数据是在一个表中的下列方式:创建SQL Server中

RptLOB1  RptLOB2 Correlation 
AE   AE    1 
Bail  AE   0.35 
Commercial Bail   0.25 
Commercial AE   0.15 

...等等。

我想写一个代码,使我的输出如下方式如下:

  AE  Bail Commercial 
AE   1  0.35  0.15 
Bail  0.35 1  0.25 
Commercial 0.15 0.25  1 

的RptLOB的顺序不只要事情的顺序是从上到下相同,从左到右最佳。我一直在试图找到一种方法来解决这个问题,我不确定最好的方法是什么。我正在考虑使用PIVOT,但不会输出RptLOB的顶部(它们将被视为表中的列)。

编辑:

此输出将被插入另一个表像这样:

col1    col2  col3       col4  col5    

Generic 
Company Inputs Insurance Stochastic Model Correlations Exposure Correlation Matrix 
       AE   Bail       Commercial 
AE    1   0.35       0.15 
Bail    0.35  1        0.25 
Commercial  0.15  0.25       1 
+0

@OMGPonies嗯,我能想到的是旋转行值的唯一的事来创建最上面一行,但如果我这样做行值变列标题,这不是我想要的。我不知道如何处理是不会发生的,我可以创建矩阵... – Kristina

+0

我认为这将是非常困难的使用纯SQL。我建议尝试其他工具,如R编程语言。 – jrara

+0

如果您不希望列成为列标题,那么您遇到了数据类型不匹配的问题。 – podiluska

回答

4

您可以使用PIVOT。如果你知道你必须改变的列数,那么你可以使用一个静态版本:

select * 
from 
(
    select RptLOB1 RptLOB1, RPTLOB2 RPTLOB2, Correlation 
    from yourtable 
    union all 
    select RPTLOB2, RptLOB1, Correlation 
    from yourtable 
    union all 
    select distinct RptLOB1, RptLOB1, 1.0 
    from yourtable 
) x 
pivot 
(
    max(Correlation) 
    for RPTLOB2 in ([AE], [Bail], [Commercial]) 
) p; 

看到SQL Fiddle with demo

如果你有一个未知的数字值相关联的,那么你将要使用动态版:

DECLARE @query AS NVARCHAR(MAX), 
    @colsPivot as NVARCHAR(MAX) 

select @colsPivot = STUFF((SELECT distinct ',' 
         + quotename(RptLOB1) 
        from yourtable t 
      FOR XML PATH(''), TYPE 
      ).value('.', 'NVARCHAR(MAX)') 
     ,1,1,'') 

set @query 
    = 'select RptLOB1, '[email protected]+ ' 
    from 
    (
     select RptLOB1 RptLOB1, RPTLOB2 RPTLOB2, Correlation 
     from yourtable 
     union all 
     select RPTLOB2, RptLOB1, Correlation 
     from yourtable 
     union all 
     select distinct RptLOB1, RptLOB1, 1.0 
     from yourtable 
    ) x 
     pivot 
     (
     max(Correlation) 
     for RPTLOB2 in ('+ @colspivot +') 
    ) p' 

exec(@query) 

看到SQL Fiddle with demo

编辑 - 根据您的意见,如果你想在另一个RO列标题W,那么你可以使用以下命令:

DECLARE @query AS NVARCHAR(MAX), 
    @colsPivot as NVARCHAR(MAX), 
    @colsRow as NVARCHAR(MAX), 
    @colsConverted as NVARCHAR(MAX) 

select @colsPivot = STUFF((SELECT distinct ',' 
         + quotename(RptLOB1) 
        from yourtable t 
      FOR XML PATH(''), TYPE 
      ).value('.', 'NVARCHAR(MAX)') 
     ,1,1,'') 

select @colsRow = STUFF((SELECT distinct ', ''' 
         + RptLOB1 + ''' as ' + RptLOB1 
        from yourtable t 
      FOR XML PATH(''), TYPE 
      ).value('.', 'NVARCHAR(MAX)') 
     ,1,1,'') 

select @colsConverted 
     = STUFF((SELECT distinct ', CAST(' 
       + quotename(RptLOB1) 
       + ' as varchar(50))' 
       from yourtable t 
      FOR XML PATH(''), TYPE 
      ).value('.', 'NVARCHAR(MAX)') 
     ,1,1,'') 


set @query 
    = 'select ''RptLOB1'' as RptLOB1, 
     '+ @colsRow + ' 
    union all 
    select RptLOB1, '+ @colsConverted+ ' 
    from 
    (
     select RptLOB1 RptLOB1, RPTLOB2 RPTLOB2, Correlation 
     from yourtable 
     union all 
     select RPTLOB2, RptLOB1, Correlation 
     from yourtable 
     union all 
     select distinct RptLOB1, RptLOB1, 1.0 
     from yourtable 
    ) x 
     pivot 
     (
     max(Correlation) 
     for RPTLOB2 in ('+ @colspivot +') 
    ) p' 

exec(@query) 

看到SQL Fiddle with demo

+0

+1个惊人的答案。 – usr

+0

非常感谢!有什么办法显示列标题(因为它包含其他RptLOB的)?这最终将在动态sql中完成。 – Kristina

+0

@Kristina我不确定你是什么意思的列标题?当获取“@ colspivot”的值时,动态sql中将检索到列标题。 – Taryn

0

的问题是,你的数据不完整不够。所以,你需要什么提升呢:

with d as (
    select RptLOB1, RptLOB2, Correlation from t union all 
    select RptLOB2, RptLOB1, Correlation from t union all 
    select distinct RptLob1, RptLob1, 1.0 from t 
) 
select RptLOB1, RptLOB2, Corr 
from d 
pivot (max(correlation) for val in ('AE', 'Bail', 'Commercial')) as corr 

如果你不知道所有的值的名称,那么你将需要动态SQL的一般情况。