Sql 两列上的枢轴运算符

Sql 两列上的枢轴运算符,sql,sql-server,pivot,Sql,Sql Server,Pivot,我对SQL非常陌生,更不用说在SSM中做数据透视了。在做了一些研究之后,我很难为两列做枢轴 查询时,数据本身是: SELECT INSTRUMENT_ID, VALUE_TYPE_CODE, ORIGINAL_TRANSACTION_VALUE, VALUE_IN_HOME_CURRENCY FROM FACT_TABLE 以原始交易价值为中心 SELECT * FROM ( SELECT INSTRUMENT_ID, VALUE_TYPE_C

我对SQL非常陌生,更不用说在SSM中做数据透视了。在做了一些研究之后,我很难为两列做枢轴

查询时,数据本身是:

SELECT
   INSTRUMENT_ID,
   VALUE_TYPE_CODE,
   ORIGINAL_TRANSACTION_VALUE,
   VALUE_IN_HOME_CURRENCY

FROM
   FACT_TABLE
以原始交易价值为中心

SELECT *
FROM
(
  SELECT INSTRUMENT_ID,
       VALUE_TYPE_CODE,
       ORIGINAL_TRANSACTION_VALUE,
       VALUE_IN_HOME_CURRENCY
  FROM FACT_TABLE
)
AS Table
PIVOT (MAX (ORIGINAL_TRANSACTION_VALUE) FOR  VALUE_TYPE_CODE IN ([TOT_AMT], 
                                                                [AMT_AVAL], 
                                                                [DRWN_AMT], 
                                                                [MTD_DRWN])) as piv
结果如预期:

INSTRUMENT_ID | TOT_AMT | AMT_AVAL | DRWN_AMT | MTD_DRWN
ABC           |3        | 1        | 2        | 2
然而,我试图产生以下结果-注意,每类值类型代码的原始交易值和本国货币值交替出现

INSTRUMENT_ID |TOT_AMT  |TOT_AMT |AMT_AVAL |AMT_AVAL |DRWN_AMT |DRWN_AMT |MTD_DRWN |MTD_DRWN
ABC           | 3       |5.7702  |  1      |1.9234   |2        |3.8468   |  2      |3.8468
所以我尝试了以下我在这里发现的方法。它看起来很简单,而且我还是新SQL,所以对我来说很有意义。复制类别值,否则PIVOT将无法正常工作

SELECT *
FROM
(
  SELECT INSTRUMENT_ID,
       VALUE_TYPE_CODE,
       VALUE_TYPE_CODE+'1' as VALUE_TYPE_CODE1,
       ORIGINAL_TRANSACTION_VALUE,
       VALUE_IN_HOME_CURRENCY
  FROM FACT_TABLE
)
AS Table
-- Pivot on ORIGINAL_TRANSACTION_VALUE
PIVOT (MAX (ORIGINAL_TRANSACTION_VALUE) FOR  VALUE_TYPE_CODE IN ([TOT_AMT], 
                                                                 [AMT_AVAL], 
                                                                 [DRWN_AMT], 
                                                                 [MTD_DRWN])) as piv
-- Pivot on VALUE_IN_HOME_CURRENCY
PIVOT (MAX (VALUE_IN_HOME_CURRENCY) FOR  VALUE_TYPE_CODE1 IN ([TOT_AMT1], 
                                                              [AMT_AVAL1], 
                                                              [DRWN_AMT1], 
                                                              [MTD_DRWN1])) as piv1
不幸的是,这并没有按照我希望的方式进行,结果是:

INSTRUMENT_ID |TOT_AMT  |TOT_AMT |AMT_AVAL |AMT_AVAL |DRWN_AMT |DRWN_AMT |MTD_DRWN |MTD_DRWN
ABC           | 3       |5.7702  |  NULL   |NULL     |NULL     |NULL     |NULL     |NULL   
ABC           | NULL    |NULL    |  1      | 1.9234  |NULL     |NULL     |NULL     |NULL 
ABC           | NULL    |NULL    |  NULL   |NULL     |2        |3.8468   |NULL     |NULL  
ABC           | NULL    |NULL    |  NULL   |NULL     |NULL     |NULL     |  2      |3.8468

我想知道是否有人能指出我做错了什么?有没有更简单的方法?也许这本身不是一个更简单的方法,但这是一个有一些解释的解决方案。我在这里寻找了一些解决方案,其中很多都超出了我的想象,因为我对这方面还是新手


我非常感谢你在这方面的帮助。谢谢。

PIVOT需要记住的是,它在该点上转换整个结果集。
PIVOT
中未提及的所有列有效地用于将结果分组到行中

因此,在您的尝试中,您的第一个
PIVOT
将根据
仪器ID
本币值对行进行分组,这就是它生成四行的原因

解决方案是两次透视原始结果集,排除不必要的列,然后合并结果

因此,让我们使用通用表表达式对其进行分解:

WITH SourceData as (
    SELECT INSTRUMENT_ID,
       VALUE_TYPE_CODE,
       ORIGINAL_TRANSACTION_VALUE,
       VALUE_IN_HOME_CURRENCY
    FROM FACT_TABLE
), OriginalPivotSource as (
    SELECT
       INSTRUMENT_ID,
       VALUE_TYPE_CODE,
       ORIGINAL_TRANSACTION_VALUE
    FROM SourceData
), OriginalPivot as (
    SELECT
        *
    FROM OriginalPivotSource
    PIVOT (MAX (ORIGINAL_TRANSACTION_VALUE) FOR  VALUE_TYPE_CODE IN ([TOT_AMT], 
                                                                 [AMT_AVAL], 
                                                                 [DRWN_AMT], 
                                                                 [MTD_DRWN])) t
), HomePivotSource as (
    SELECT
       INSTRUMENT_ID,
       VALUE_TYPE_CODE,
       VALUE_IN_HOME_CURRENCY
    FROM
        SourceData
), HomePivot as (
    SELECT
        *
    FROM HomePivotSource
    PIVOT (MAX (VALUE_IN_HOME_CURRENCY) FOR  VALUE_TYPE_CODE IN ([TOT_AMT], 
                                                              [AMT_AVAL], 
                                                              [DRWN_AMT], 
                                                              [MTD_DRWN])) t
)
SELECT
    *
FROM
    OriginalPivot op
        FULL OUTER JOIN
    HomePivot hp
        on
           op.INSTRUMENT_ID = hp.INSTRUMENT_ID

使用
PIVOT
时要记住的一点是,它在该点上转换整个结果集。
PIVOT
中未提及的所有列有效地用于将结果分组到行中

因此,在您的尝试中,您的第一个
PIVOT
将根据
仪器ID
本币值对行进行分组,这就是它生成四行的原因

解决方案是两次透视原始结果集,排除不必要的列,然后合并结果

因此,让我们使用通用表表达式对其进行分解:

WITH SourceData as (
    SELECT INSTRUMENT_ID,
       VALUE_TYPE_CODE,
       ORIGINAL_TRANSACTION_VALUE,
       VALUE_IN_HOME_CURRENCY
    FROM FACT_TABLE
), OriginalPivotSource as (
    SELECT
       INSTRUMENT_ID,
       VALUE_TYPE_CODE,
       ORIGINAL_TRANSACTION_VALUE
    FROM SourceData
), OriginalPivot as (
    SELECT
        *
    FROM OriginalPivotSource
    PIVOT (MAX (ORIGINAL_TRANSACTION_VALUE) FOR  VALUE_TYPE_CODE IN ([TOT_AMT], 
                                                                 [AMT_AVAL], 
                                                                 [DRWN_AMT], 
                                                                 [MTD_DRWN])) t
), HomePivotSource as (
    SELECT
       INSTRUMENT_ID,
       VALUE_TYPE_CODE,
       VALUE_IN_HOME_CURRENCY
    FROM
        SourceData
), HomePivot as (
    SELECT
        *
    FROM HomePivotSource
    PIVOT (MAX (VALUE_IN_HOME_CURRENCY) FOR  VALUE_TYPE_CODE IN ([TOT_AMT], 
                                                              [AMT_AVAL], 
                                                              [DRWN_AMT], 
                                                              [MTD_DRWN])) t
)
SELECT
    *
FROM
    OriginalPivot op
        FULL OUTER JOIN
    HomePivot hp
        on
           op.INSTRUMENT_ID = hp.INSTRUMENT_ID

主要的问题是,您为pivot语句提供的列比正在透视的列更多
piv
的枢轴操作不需要
本币价值
piv1
不需要
原始交易价值

此问题有几种解决方案:

  • 在当前解决方案中添加一个
    分组依据
    和一些聚合
  • 将枢轴操作拆分为两个单独的操作,并在
    仪器ID
    上重新连接它们
  • 取消分割原始数据,使
    原始交易值
    本币值
    为一列,然后一次转换为8列。在单个列中获取所有值确实需要所有值的兼容数据类型
  • 样本数据

    create table FACT_TABLE
    (
       INSTRUMENT_ID nvarchar(3),
       VALUE_TYPE_CODE nvarchar(10),
       ORIGINAL_TRANSACTION_VALUE int,
       VALUE_IN_HOME_CURRENCY money,
    );
    
    insert into FACT_TABLE (INSTRUMENT_ID, VALUE_TYPE_CODE, ORIGINAL_TRANSACTION_VALUE, VALUE_IN_HOME_CURRENCY) values
    ('ABC', 'TOT_AMT' , 3, 5.7702),
    ('ABC', 'AMT_AVAL', 1, 1.9234),
    ('ABC', 'DRWN_AMT', 2, 3.8468),
    ('ABC', 'MTD_DRWN', 2, 3.8468);
    
    解决方案1

    SELECT piv1.INSTRUMENT_ID,
           max(piv1.TOT_AMT)   as TOT_AMT,
           max(piv1.TOT_AMT1)  as TOT_AMT1,
           max(piv1.AMT_AVAL)  as AMT_AVAL,
           max(piv1.AMT_AVAL1) as AMT_AVAL1,
           max(piv1.DRWN_AMT)  as DRWN_AMT,
           max(piv1.DRWN_AMT1) as DRWN_AMT1,
           max(piv1.MTD_DRWN)  as MTD_DRWN,
           max(piv1.MTD_DRWN1) as MTD_DRWN1
    FROM
    (
      SELECT INSTRUMENT_ID,
           VALUE_TYPE_CODE,
           VALUE_TYPE_CODE+'1' as VALUE_TYPE_CODE1,
           ORIGINAL_TRANSACTION_VALUE,
           VALUE_IN_HOME_CURRENCY
      FROM FACT_TABLE
    )
    AS T
    -- Pivot on ORIGINAL_TRANSACTION_VALUE
    PIVOT (MAX (ORIGINAL_TRANSACTION_VALUE) FOR  VALUE_TYPE_CODE IN ([TOT_AMT], 
                                                                     [AMT_AVAL], 
                                                                     [DRWN_AMT], 
                                                                     [MTD_DRWN])) as piv
    -- Pivot on VALUE_IN_HOME_CURRENCY
    PIVOT (MAX (VALUE_IN_HOME_CURRENCY) FOR  VALUE_TYPE_CODE1 IN ([TOT_AMT1], 
                                                                  [AMT_AVAL1], 
                                                                  [DRWN_AMT1], 
                                                                  [MTD_DRWN1])) as piv1
    group by piv1.INSTRUMENT_ID
    
    解决方案2

    with cte_piv as
    (
      -- Pivot on ORIGINAL_TRANSACTION_VALUE
      select piv.INSTRUMENT_ID,
             piv.TOT_AMT,
             piv.AMT_AVAL,
             piv.DRWN_AMT,
             piv.MTD_DRWN
      from ( SELECT INSTRUMENT_ID, VALUE_TYPE_CODE, ORIGINAL_TRANSACTION_VALUE
             FROM FACT_TABLE ) T
      PIVOT (MAX (ORIGINAL_TRANSACTION_VALUE) FOR  VALUE_TYPE_CODE IN ([TOT_AMT], 
                                                                     [AMT_AVAL], 
                                                                     [DRWN_AMT], 
                                                                     [MTD_DRWN])) as piv
    ),
    cte_piv1 as
    (
      -- Pivot on VALUE_IN_HOME_CURRENCY
      select piv1.INSTRUMENT_ID,
             piv1.TOT_AMT,
             piv1.AMT_AVAL,
             piv1.DRWN_AMT,
             piv1.MTD_DRWN
      from ( SELECT INSTRUMENT_ID, VALUE_TYPE_CODE, VALUE_IN_HOME_CURRENCY
             FROM FACT_TABLE ) T
      PIVOT (MAX (VALUE_IN_HOME_CURRENCY) FOR  VALUE_TYPE_CODE IN ([TOT_AMT], 
                                                                  [AMT_AVAL], 
                                                                  [DRWN_AMT], 
                                                                  [MTD_DRWN])) as piv1
    )
    select p.INSTRUMENT_ID,
           p.TOT_AMT,
           p1.TOT_AMT,
           p.AMT_AVAL,
           p1.AMT_AVAL,
           p.DRWN_AMT,
           p1.DRWN_AMT,
           p.MTD_DRWN,
           p1.MTD_DRWN
    from cte_piv p
    join cte_piv1 p1 on p1.INSTRUMENT_ID = p.INSTRUMENT_ID
    
    解决方案3

    with cte as
    (
      SELECT INSTRUMENT_ID,
             VALUE_TYPE_CODE,
              -- all values require a compatible type for a pivot
             convert(money, ORIGINAL_TRANSACTION_VALUE) as ORIGINAL_TRANSACTION_VALUE,
             VALUE_IN_HOME_CURRENCY
     FROM FACT_TABLE
    ),
    cte2 as
    (
      select up.INSTRUMENT_ID,
             up.VALUE_TYPE_CODE + '_' + left(up.ValueType, 4) as NEW_CODE,
             up.Value
      from cte
      unpivot (Value for ValueType in (ORIGINAL_TRANSACTION_VALUE, VALUE_IN_HOME_CURRENCY)) up
    )
    select p.INSTRUMENT_ID,
           convert(int, p.TOT_AMT_ORIG)  as TOT_AMT,
           p.TOT_AMT_VALU                as TOT_AMT1,
           convert(int, p.AMT_AVAL_ORIG) as AMT_AVAL,
           p.AMT_AVAL_VALU               as AMT_AVAL1,
           convert(int, p.DRWN_AMT_ORIG) as DRWN_AMT,
           p.DRWN_AMT_ORIG               as DRWN_AMT1,
           convert(int, p.MTD_DRWN_ORIG) as MTD_DRWN,
           p.DRWN_AMT_VALU               as MTD_DRWN1,
           convert(int, p.MTD_DRWN_ORIG) as MTD_DRWN,
           p.MTD_DRWN_VALU               as MTD_DRWN1
    from cte2
    pivot (max(Value) for NEW_CODE in ([TOT_AMT_ORIG],  [TOT_AMT_VALU],
                                       [AMT_AVAL_ORIG], [AMT_AVAL_VALU],
                                       [DRWN_AMT_ORIG], [DRWN_AMT_VALU],
                                       [MTD_DRWN_ORIG], [MTD_DRWN_VALU])) p
    
    =解决方案1和2

    =解决方案3

    主要问题是,为pivot语句提供的列比正在透视的列更多
    piv
    的枢轴操作不需要
    本币价值
    piv1
    不需要
    原始交易价值

    此问题有几种解决方案:

  • 在当前解决方案中添加一个
    分组依据
    和一些聚合
  • 将枢轴操作拆分为两个单独的操作,并在
    仪器ID
    上重新连接它们
  • 取消分割原始数据,使
    原始交易值
    本币值
    为一列,然后一次转换为8列。在单个列中获取所有值确实需要所有值的兼容数据类型
  • 样本数据

    create table FACT_TABLE
    (
       INSTRUMENT_ID nvarchar(3),
       VALUE_TYPE_CODE nvarchar(10),
       ORIGINAL_TRANSACTION_VALUE int,
       VALUE_IN_HOME_CURRENCY money,
    );
    
    insert into FACT_TABLE (INSTRUMENT_ID, VALUE_TYPE_CODE, ORIGINAL_TRANSACTION_VALUE, VALUE_IN_HOME_CURRENCY) values
    ('ABC', 'TOT_AMT' , 3, 5.7702),
    ('ABC', 'AMT_AVAL', 1, 1.9234),
    ('ABC', 'DRWN_AMT', 2, 3.8468),
    ('ABC', 'MTD_DRWN', 2, 3.8468);
    
    解决方案1

    SELECT piv1.INSTRUMENT_ID,
           max(piv1.TOT_AMT)   as TOT_AMT,
           max(piv1.TOT_AMT1)  as TOT_AMT1,
           max(piv1.AMT_AVAL)  as AMT_AVAL,
           max(piv1.AMT_AVAL1) as AMT_AVAL1,
           max(piv1.DRWN_AMT)  as DRWN_AMT,
           max(piv1.DRWN_AMT1) as DRWN_AMT1,
           max(piv1.MTD_DRWN)  as MTD_DRWN,
           max(piv1.MTD_DRWN1) as MTD_DRWN1
    FROM
    (
      SELECT INSTRUMENT_ID,
           VALUE_TYPE_CODE,
           VALUE_TYPE_CODE+'1' as VALUE_TYPE_CODE1,
           ORIGINAL_TRANSACTION_VALUE,
           VALUE_IN_HOME_CURRENCY
      FROM FACT_TABLE
    )
    AS T
    -- Pivot on ORIGINAL_TRANSACTION_VALUE
    PIVOT (MAX (ORIGINAL_TRANSACTION_VALUE) FOR  VALUE_TYPE_CODE IN ([TOT_AMT], 
                                                                     [AMT_AVAL], 
                                                                     [DRWN_AMT], 
                                                                     [MTD_DRWN])) as piv
    -- Pivot on VALUE_IN_HOME_CURRENCY
    PIVOT (MAX (VALUE_IN_HOME_CURRENCY) FOR  VALUE_TYPE_CODE1 IN ([TOT_AMT1], 
                                                                  [AMT_AVAL1], 
                                                                  [DRWN_AMT1], 
                                                                  [MTD_DRWN1])) as piv1
    group by piv1.INSTRUMENT_ID
    
    解决方案2

    with cte_piv as
    (
      -- Pivot on ORIGINAL_TRANSACTION_VALUE
      select piv.INSTRUMENT_ID,
             piv.TOT_AMT,
             piv.AMT_AVAL,
             piv.DRWN_AMT,
             piv.MTD_DRWN
      from ( SELECT INSTRUMENT_ID, VALUE_TYPE_CODE, ORIGINAL_TRANSACTION_VALUE
             FROM FACT_TABLE ) T
      PIVOT (MAX (ORIGINAL_TRANSACTION_VALUE) FOR  VALUE_TYPE_CODE IN ([TOT_AMT], 
                                                                     [AMT_AVAL], 
                                                                     [DRWN_AMT], 
                                                                     [MTD_DRWN])) as piv
    ),
    cte_piv1 as
    (
      -- Pivot on VALUE_IN_HOME_CURRENCY
      select piv1.INSTRUMENT_ID,
             piv1.TOT_AMT,
             piv1.AMT_AVAL,
             piv1.DRWN_AMT,
             piv1.MTD_DRWN
      from ( SELECT INSTRUMENT_ID, VALUE_TYPE_CODE, VALUE_IN_HOME_CURRENCY
             FROM FACT_TABLE ) T
      PIVOT (MAX (VALUE_IN_HOME_CURRENCY) FOR  VALUE_TYPE_CODE IN ([TOT_AMT], 
                                                                  [AMT_AVAL], 
                                                                  [DRWN_AMT], 
                                                                  [MTD_DRWN])) as piv1
    )
    select p.INSTRUMENT_ID,
           p.TOT_AMT,
           p1.TOT_AMT,
           p.AMT_AVAL,
           p1.AMT_AVAL,
           p.DRWN_AMT,
           p1.DRWN_AMT,
           p.MTD_DRWN,
           p1.MTD_DRWN
    from cte_piv p
    join cte_piv1 p1 on p1.INSTRUMENT_ID = p.INSTRUMENT_ID
    
    解决方案3

    with cte as
    (
      SELECT INSTRUMENT_ID,
             VALUE_TYPE_CODE,
              -- all values require a compatible type for a pivot
             convert(money, ORIGINAL_TRANSACTION_VALUE) as ORIGINAL_TRANSACTION_VALUE,
             VALUE_IN_HOME_CURRENCY
     FROM FACT_TABLE
    ),
    cte2 as
    (
      select up.INSTRUMENT_ID,
             up.VALUE_TYPE_CODE + '_' + left(up.ValueType, 4) as NEW_CODE,
             up.Value
      from cte
      unpivot (Value for ValueType in (ORIGINAL_TRANSACTION_VALUE, VALUE_IN_HOME_CURRENCY)) up
    )
    select p.INSTRUMENT_ID,
           convert(int, p.TOT_AMT_ORIG)  as TOT_AMT,
           p.TOT_AMT_VALU                as TOT_AMT1,
           convert(int, p.AMT_AVAL_ORIG) as AMT_AVAL,
           p.AMT_AVAL_VALU               as AMT_AVAL1,
           convert(int, p.DRWN_AMT_ORIG) as DRWN_AMT,
           p.DRWN_AMT_ORIG               as DRWN_AMT1,
           convert(int, p.MTD_DRWN_ORIG) as MTD_DRWN,
           p.DRWN_AMT_VALU               as MTD_DRWN1,
           convert(int, p.MTD_DRWN_ORIG) as MTD_DRWN,
           p.MTD_DRWN_VALU               as MTD_DRWN1
    from cte2
    pivot (max(Value) for NEW_CODE in ([TOT_AMT_ORIG],  [TOT_AMT_VALU],
                                       [AMT_AVAL_ORIG], [AMT_AVAL_VALU],
                                       [DRWN_AMT_ORIG], [DRWN_AMT_VALU],
                                       [MTD_DRWN_ORIG], [MTD_DRWN_VALU])) p
    
    =解决方案1和2

    =解决方案3此答案适用于希望将其动态化的观众。[列值是动态的]

    对于MSSQL服务器

    DECLARE @cols1 AS NVARCHAR(MAX),@cols2 AS NVARCHAR(MAX),@selectcolumn1 AS NVARCHAR(MAX),@selectcolumn2 AS NVARCHAR(MAX),
       @selectcolumn AS NVARCHAR(MAX), @query  AS NVARCHAR(MAX);
        SET @cols1 = STUFF((SELECT distinct ',' + QUOTENAME(f.VALUE_TYPE_CODE) 
                FROM FACT_TABLE f
                FOR XML PATH(''), TYPE
                ).value('.', 'NVARCHAR(MAX)') 
            ,1,1,'') 
        SET @cols2 = STUFF((SELECT distinct ',' + QUOTENAME(f.VALUE_TYPE_CODE+'1')
                FROM FACT_TABLE f
                FOR XML PATH(''), TYPE
                ).value('.', 'NVARCHAR(MAX)') 
            ,1,1,'') 
    
        SET @selectcolumn1 = STUFF((SELECT distinct ',MAX(piv1.' + f.VALUE_TYPE_CODE+') as '+ f.VALUE_TYPE_CODE+'_OTV'
            FROM FACT_TABLE f
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'') 
    
        SET @selectcolumn2 = STUFF((SELECT distinct ',MAX(piv1.' + f.VALUE_TYPE_CODE+'1) as '+ f.VALUE_TYPE_CODE+'_HC'
            FROM FACT_TABLE f
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')
    
      set @selectcolumn=concat(@selectcolumn1,',',@selectcolumn2)
    
    set @query = 'SELECT piv1.INSTRUMENT_ID,
           '+@selectcolumn+'
    FROM
    (
      SELECT INSTRUMENT_ID,
           VALUE_TYPE_CODE,
           VALUE_TYPE_CODE+''1'' as VALUE_TYPE_CODE1,
           ORIGINAL_TRANSACTION_VALUE,
           VALUE_IN_HOME_CURRENCY
      FROM FACT_TABLE
    )
    AS T
    PIVOT (MAX (ORIGINAL_TRANSACTION_VALUE) FOR  VALUE_TYPE_CODE IN ('+@cols1+')) as piv
    PIVOT (MAX (VALUE_IN_HOME_CURRENCY) FOR  VALUE_TYPE_CODE1 IN ('+@cols2+')) as piv1
                                                                  
    group by piv1.INSTRUMENT_ID'
    
    execute(@query)
    
    
    对于MYSQL服务器

    SET @col1 = NULL;
    SET @col2 = NULL;
    SET @sql = NULL;
    SELECT
      GROUP_CONCAT(DISTINCT
        CONCAT(      
     
           'Max(IF(f.VALUE_TYPE_CODE = ''',VALUE_TYPE_CODE,''', ORIGINAL_TRANSACTION_VALUE, Null)) as ',VALUE_TYPE_CODE,'_OT'
        )
      ) INTO @col1
    FROM FACT_TABLE;
    
    SELECT
      GROUP_CONCAT(DISTINCT
        CONCAT(      
     
           'Max(IF(f.VALUE_TYPE_CODE1 = ''',VALUE_TYPE_CODE,'1'', VALUE_IN_HOME_CURRENCY, Null)) as ',VALUE_TYPE_CODE,'_HC'
        )
      ) INTO @col2
    FROM FACT_TABLE;
    
    
    
    SET @sql = CONCAT('SELECT 
        f.INSTRUMENT_ID,  ', CONCAT(@col1,',',@col2) , 
        ' FROM  (SELECT INSTRUMENT_ID,VALUE_TYPE_CODE,CONCAT(VALUE_TYPE_CODE,''1'') AS VALUE_TYPE_CODE1,ORIGINAL_TRANSACTION_VALUE,VALUE_IN_HOME_CURRENCY FROM FACT_TABLE) f
       Group by f.INSTRUMENT_ID');
      
    PREPARE stmt FROM @sql;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;
       
    
    
    
    

    这个答案是为那些想让它充满活力的观众准备的。[列值是动态的]

    对于MSSQL服务器

    DECLARE @cols1 AS NVARCHAR(MAX),@cols2 AS NVARCHAR(MAX),@selectcolumn1 AS NVARCHAR(MAX),@selectcolumn2 AS NVARCHAR(MAX),
       @selectcolumn AS NVARCHAR(MAX), @query  AS NVARCHAR(MAX);
        SET @cols1 = STUFF((SELECT distinct ',' + QUOTENAME(f.VALUE_TYPE_CODE) 
                FROM FACT_TABLE f
                FOR XML PATH(''), TYPE
                ).value('.', 'NVARCHAR(MAX)') 
            ,1,1,'') 
        SET @cols2 = STUFF((SELECT distinct ',' + QUOTENAME(f.VALUE_TYPE_CODE+'1')
                FROM FACT_TABLE f
                FOR XML PATH(''), TYPE
                ).value('.', 'NVARCHAR(MAX)') 
            ,1,1,'') 
    
        SET @selectcolumn1 = STUFF((SELECT distinct ',MAX(piv1.' + f.VALUE_TYPE_CODE+') as '+ f.VALUE_TYPE_CODE+'_OTV'
            FROM FACT_TABLE f
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'') 
    
        SET @selectcolumn2 = STUFF((SELECT distinct ',MAX(piv1.' + f.VALUE_TYPE_CODE+'1) as '+ f.VALUE_TYPE_CODE+'_HC'
            FROM FACT_TABLE f
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')
    
      set @selectcolumn=concat(@selectcolumn1,',',@selectcolumn2)
    
    set @query = 'SELECT piv1.INSTRUMENT_ID,
           '+@selectcolumn+'
    FROM
    (
      SELECT INSTRUMENT_ID,
           VALUE_TYPE_CODE,
           VALUE_TYPE_CODE+''1'' as VALUE_TYPE_CODE1,
           ORIGINAL_TRANSACTION_VALUE,
           VALUE_IN_HOME_CURRENCY
      FROM FACT_TABLE
    )
    AS T
    PIVOT (MAX (ORIGINAL_TRANSACTION_VALUE) FOR  VALUE_TYPE_CODE IN ('+@cols1+')) as piv
    PIVOT (MAX (VALUE_IN_HOME_CURRENCY) FOR  VALUE_TYPE_CODE1 IN ('+@cols2+')) as piv1
                                                                  
    group by piv1.INSTRUMENT_ID'
    
    execute(@query)
    
    
    对于MYSQL服务器

    SET @col1 = NULL;
    SET @col2 = NULL;
    SET @sql = NULL;
    SELECT
      GROUP_CONCAT(DISTINCT
        CONCAT(      
     
           'Max(IF(f.VALUE_TYPE_CODE = ''',VALUE_TYPE_CODE,''', ORIGINAL_TRANSACTION_VALUE, Null)) as ',VALUE_TYPE_CODE,'_OT'
        )
      ) INTO @col1
    FROM FACT_TABLE;
    
    SELECT
      GROUP_CONCAT(DISTINCT
        CONCAT(      
     
           'Max(IF(f.VALUE_TYPE_CODE1 = ''',VALUE_TYPE_CODE,'1'', VALUE_IN_HOME_CURRENCY, Null)) as ',VALUE_TYPE_CODE,'_HC'
        )
      ) INTO @col2
    FROM FACT_TABLE;
    
    
    
    SET @sql = CONCAT('SELECT 
        f.INSTRUMENT_ID,  ', CONCAT(@col1,',',@col2) , 
        ' FROM  (SELECT INSTRUMENT_ID,VALUE_TYPE_CODE,CONCAT(VALUE_TYPE_CODE,''1'') AS VALUE_TYPE_CODE1,ORIGINAL_TRANSACTION_VALUE,VALUE_IN_HOME_CURRENCY FROM FACT_TABLE) f
       Group by f.INSTRUMENT_ID');
      
    PREPARE stmt FROM @sql;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;
       
    
    
    
    

    谢谢你!从您提供的解决方案列表中,考虑到我的总体查询量很大,考虑到我的情况,解决方案2对我来说通常是可以直接使用的。有一件事我想问一下..看起来WITH+CTE在整个查询之前?谢谢!从您提供的解决方案列表中,考虑到我的总体查询量很大,考虑到我的情况,解决方案2对我来说通常是可以直接使用的。有一件事我想问..WITH+CTE似乎在整个查询之前?