代码之家  ›  专栏  ›  技术社区  ›  GDroid

如何将SQL Server行数据转换为列?

  •  0
  • GDroid  · 技术社区  · 8 年前

    我这样查询数据

    member_no cover_version product_id product_name         product_type
    --------- ------------- ---------- -------------------- ------------
    11421     7                      4 Excellent More       E           
    11421     7                     15 Comprehensive Data   D           
    

    但我想把这个数据塑造成这样:

    member_no cover_version product_e_id product_e_name       product_d_id product_d_name
    --------- ------------- ------------ -------------------- ------------ --------------------
    11421     7                        4 Excellent More                 15 Comprehensive Data  
    

    我使用的是SQL Server 2008。按照我的要求塑造数据的最佳方法应该是什么?

    2 回复  |  直到 8 年前
        1
  •  2
  •   Liesel    8 年前

    假设您只拥有所述的产品类型D和E,那么一个简单的自连接就可以满足您的需求。

    如果你想要更通用的东西,请扩展你的问题。

    DROP TABLE IF EXISTS #Demo
    
    SELECT
        *
    INTO
        #Demo
    FROM
        (VALUES 
        (11421, 7, 4, 'Excellent More', 'E')
       ,(11421, 7, 15, 'Comprehensive Data', 'D'))  A
        (member_no, cover_version, product_id, product_name, product_type) 
    
    SELECT
        D.member_no
       ,D.cover_version
       ,E.product_id product_e_id
       ,E.product_name product_e_name
       ,D.product_id product_d_id
       ,D.product_name product_d_name
    FROM
        #Demo D
    JOIN #Demo E ON D.member_no = E.member_no
                    AND D.product_type = 'D'
                    AND E.product_type = 'E';
    
    
    member_no   cover_version product_e_id product_e_name     product_d_id product_d_name
    ----------- ------------- ------------ ------------------ ------------ ------------------
    11421       7             4            Excellent More     15           Comprehensive Data
    
        2
  •  1
  •   JamieD77    8 年前

    如果您想基于未知的产品类型动态地执行此操作,可以使用此方法。

    DECLARE @SQL NVARCHAR(MAX),
            @Columns NVARCHAR(MAX),
            @CaseExpressions NVARCHAR(MAX) = 'MAX(CASE WHEN product_type = ''<<productType>>'' THEN product_id END) AS [product_<<productType>>_id],
                                              MAX(CASE WHEN product_type = ''<<productType>>'' THEN product_name END) AS [product_<<productType>>_name]'
    
    -- build concatenated string with 2 columns for each product_type in your table.
    -- group by product_type to get distinct results.
    -- replaces <<productType>> with the actual product_type value
    SELECT  @Columns = COALESCE(@Columns + ',', '') + REPLACE(@CaseExpressions, '<<productType>>', product_type)
    FROM    myTable
    GROUP BY product_type
    
    -- build select query
    SET     @SQL = 'SELECT  member_no, cover_version,' + @Columns + ' FROM myTable GROUP BY member_no, cover_version'
    
    -- to see what the dynamic sql looks like
    PRINT   @SQL 
    
    -- to execute the dynamic sql and see result
    EXEC    (@SQL)