【问题标题】:SQL Transpose Data with Column Name带有列名的 SQL 转置数据
【发布时间】:2018-03-19 16:25:04
【问题描述】:

我正在尝试将 SQL Server 表中的数据转置,其中包含一行数据但有几列,全部与它们各自的列标题一起放入一列中。

原始数据表:

**TABLE Column Names:**   Id, ColumnA , ColumnB , ColumnC , StartDate

**Data:**                 1, 'aa' , 'bb' , 'cc', 2016-10-10

所需的数据格式:

**ColumnName     Values**
Id               1
ColumnA         aa
ColumnB         bb
ColumnC         cc
StartDate     2016-10-10


CREATE DATABASE ToDelete
GO

USE [ToDelete]
GO

CREATE TABLE [dbo].[sourceData](
    [id] [int] NULL,
    [ColumnA] [varchar](50) NULL,
    [ColumnB] [varchar](50) NULL,
    [ColumnC] [varchar](50) NULL,
    [StartDate] [datetime] NULL
) 
GO
INSERT [dbo].[sourceData] ([id], [ColumnA], [ColumnB], [ColumnC], [StartDate], [EndDate]) VALUES (1, 'aa', N'bb', N'cc', GETDATE())
GO

我用来提取表列名的查询是:

SELECT c.name
FROM sys.tables t
JOIN sys.columns c
ON t.object_id = c.object_id
WHERE t.name = 'sourceData'

您的帮助将不胜感激。

谢谢

【问题讨论】:

标签: sql sql-server tsql transpose unpivot


【解决方案1】:

这里有一个选项可以帮助您创建更像 EAV 结构的东西

示例

Declare @YourTable Table ([Id] varchar(50),[ColumnA] varchar(50),[ColumnB] varchar(50),[ColumnC] varchar(50),[StartDate] date)
Insert Into @YourTable Values 
 (1,'aa','bb','cc','2016-10-10')


Select A.ID
      ,C.*
 From @YourTable A
 Cross Apply ( values (cast((Select A.* for XML RAW) as xml))) B(XMLData)
 Cross Apply (
                Select Field = a.value('local-name(.)','varchar(100)')
                      ,Value = a.value('.','varchar(max)') 
                 From  B.XMLData.nodes('/row')  as C1(n)
                 Cross Apply C1.n.nodes('./@*') as C2(a)
                 Where a.value('local-name(.)','varchar(100)') not in ('ID','OtherColumnsTo','Exclude')
             ) C

退货

ID  Field       Value
1   ColumnA     aa
1   ColumnB     bb
1   ColumnC     cc
1   StartDate   2016-10-10

【讨论】:

  • 当我看到一个带有 cross apply 和 XML 函数的查询时,它通常是你的。感谢您弄清楚了这些东西。
  • @GordonLinoff 谢谢。我只是一个懒惰的懒人,不得不消耗一些荒谬的结构...... :)
【解决方案2】:

像这样简单地使用Union all

select Id,'ColumnA' columnName, ColumnA  [Values]
from t
union all
select Id,'ColumnB' , ColumnB 
from t
union all
select Id,'ColumnC' , ColumnC
from t
union all
select Id,'StartDate' , cast(StartDate as nvarchar(max))
from t;

SQL Fiddle Demo

【讨论】:

    【解决方案3】:

    尝试以下解决方案,我参考了以下文章来编写此查询: https://www.red-gate.com/simple-talk/sql/t-sql-programming/questions-about-pivoting-data-in-sql-server-you-were-too-shy-to-ask/

    USE [ToDelete]
    GO
    DECLARE @sql AS NVARCHAR(2000);DECLARE @col AS NVARCHAR(2000);
    DECLARE @col1 AS NVARCHAR(2000);
    
    SELECT @col = ISNULL(@col + ', ', '') + 
    concat('cast(',QUOTENAME(column_name),'as nvarchar(max))',' ',
    QUOTENAME(column_name) ),@col1=ISNULL(@col1 + ', ', '') +QUOTENAME(column_name)
    FROM (SELECT DISTINCT column_name FROM INFORMATION_SCHEMA.COLUMNS where TABLE_NAME='sourceData') AS Colname;
    
    SET @sql =N'select columnname,[values] from (select '+@col+ ' from dbo.sourceData) as D Unpivot
    ([values] for columnname in (' + @col1 + '))
    as unpiv'
    
    EXEC sp_executesql @sql;
    

    【讨论】:

      【解决方案4】:

      使用unpivot的其他变体:

      数据集

      DECLARE @YourTable TABLE
      ([Id]        VARCHAR(10),
       [ColumnA]   VARCHAR(10),
       [ColumnB]   VARCHAR(10),
       [ColumnC]   VARCHAR(10),
       [StartDate] DATE
      );
      INSERT INTO @YourTable
      VALUES
      (1, 'aa', 'bb', 'cc', '2016-10-10'),
      (2, 'cc', 'dd', 'zz', '2016-10-11');
      

      查询

      SELECT Id,
             Field,
             [Value]
      FROM
      (   SELECT Id,
                 ColumnA,
                 ColumnB,
                 ColumnC,
                 CONVERT(VARCHAR(10), StartDate) AS StartDate
          FROM @YourTable
      ) AS t UNPIVOT([Value] FOR [Field] IN ( ColumnA,
                                              ColumnB,
                                              ColumnC,
                                              StartDate)) up;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-01-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-11-03
        • 1970-01-01
        相关资源
        最近更新 更多