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

将SQL列转置到行上

  •  1
  • jackfrost5234  · 技术社区  · 6 年前

    CREATE TABLE [dbo].[ID x Values](
        IDNumber [varchar](50) NULL,
        [3001] [varchar](50) NULL,
        [3013] [varchar](50) NULL,
        [3020] [varchar](50) NULL
    )
    
    INSERT INTO [dbo].[ID x Values]
               ([IDNumber]
               ,[3001]
               ,[3013]
               ,[3020])
    Values('1111', '1', '', ''),
    ('2222', '', '2', ''),
    ('3333', '23', '', '4'),
    ('4444', '1', '', '2')
    

    第一列是项目ID。以下列是某些虚拟项目的LocationID和库存级别。即,物料ID 1111在位置3001处有1个库存物料,3013处有0个库存物料,3020处有0个库存物料。

    我在编写将这些列转换为单行记录的查询时遇到了一些问题。我想要的结果是:

    ItemID   LocationID   InventoryLevel
    -------  -----------  ---------------
    1111     3001         1
    2222     3013         2
    3333     3001         23
    3333     3020         4
    4444     3001         1
    4444     3020         2
    
    2 回复  |  直到 6 年前
        1
  •  1
  •   Jason W    6 年前

    你可以用 UNPIVOT

    SELECT
        IDNumber AS ItemID,
        LocationID,
        InventoryLevel
    FROM [dbo].[ID x Values]
        UNPIVOT (InventoryLevel FOR LocationID IN ([3001], [3013], [3020])) UNPVT
    WHERE LEN(InventoryLevel) > 0
    
        2
  •  1
  •   D-Shih    6 年前

    我会用 CROSS APPLY VALUES

    SELECT t1.IDNumber,v.LocationID,v.InventoryLevel
    FROM [ID x Values] t1 
    CROSS APPLY(
        VALUES(3001,t1.[3001]),(3013,t1.[3013]),(3020,t1.[3020])
    ) v(LocationID ,InventoryLevel)
    where InventoryLevel <> ''
    

    sqlfiddle