【问题标题】:TSQL transform row values into one column tableTSQL 将行值转换为一个列表
【发布时间】:2013-09-04 18:07:25
【问题描述】:

源表

Col1  |Col2  |Col3  |Col4  | Col5
----------------------------------
 hi   | this | is   | a    | test

目标表

RowValues|
----------
hi
this
is
a
test

我正在使用动态 SQL。 有什么帮助吗?

这是我的代码,只需将 where 子句中的表名和 Id 更改为适合您的内容

DECLARE @sql nVARCHAR(max), @TableName  nvarchar(100), @where nvarchar(max)
set @TableName = 'stockItems'

set @where= ' where id = 2'
select @sql  ='Select '
select  @sql = @sql+  + ' '''+ [name] +' = ''+ cast(' + [name]  + ' as nvarchar(10)) as '+[name]+',  ' 
         from sys.columns where object_name (object_id) = @TableName


set @sql = stuff(@sql, len(@sql), 1, '')  +  ' From '+@TableName+ @where
print @sql
set @sql = REPLACE(@sql,',   From',' From')
set @sql = @sql + '  '
print @sql
exec(@sql) 

现在我需要创建一个新表,其中有一列将每个值保存为一行

感谢@Mahmoud-Gamal 解决方案应该如下所示

declare @cols nvarchar(max)
select @cols = STUFF((SELECT distinct ',' +
                        QUOTENAME(column_name)
                      FROM information_schema.columns
                      WHERE table_name = 'vehicles' 
                      FOR XML PATH(''), TYPE
                     ).value('.', 'NVARCHAR(MAX)') 
                        , 1, 1, '');
declare @statement nvarchar(max)
set @statement ='
SELECT
    ColumnName,  Value
FROM
    Vehicles
UNPIVOT
    (
    Value
    FOR ColumnName
    IN
        (
        '+@cols+'
        )
    )
    AS A'

    execute(@statement)

请将“vehicle”表名更改为数据库中包含不同类型(datetime、int 和 nvarchar)列的任何表,并显示以下错误 有什么帮助吗? “描述”列的类型与 UNPIVOT 列表中指定的其他列的类型冲突。

【问题讨论】:

    标签: sql-server tsql unpivot


    【解决方案1】:

    使用UNPIVOT 表运算符:

    SELECT col AS RowValues
    FROM table1 AS t
    UNPIVOT
    (
      col
      FOR value IN([col1], 
                   [col2], 
                   [col3],
                  [col4],
                  [col5])
    ) AS u;
    

    这会给你:

    | ROWVALUES |
    |-----------|
    |        hi |
    |      this |
    |        is |
    |         a |
    |      test |
    

    更新:

    如果您不知道列的名称,并且想要动态执行此操作,则必须使用动态 SQL 执行此操作。

    但问题是如何获取列名?

    您可以从information_schema.columns 中获取列名,然后将它们连接到一个sql 中,然后用此字符串替换UNPIVOT 中的列名,然后像这样动态执行该语句:

    DECLARE @cols AS NVARCHAR(MAX);
    DECLARE @query AS NVARCHAR(MAX);
    
    select @cols = STUFF((SELECT distinct ',' +
                            QUOTENAME(column_name)
                          FROM information_schema.columns
                          WHERE table_name = 'Table1'
                          FOR XML PATH(''), TYPE
                         ).value('.', 'NVARCHAR(MAX)') 
                            , 1, 1, '');
    
    SELECT @query = ' SELECT col AS RowValues
                      FROM table1 AS t
                      UNPIVOT
                      (
                      val
                      FOR col IN ( ' + @cols + ' )
                      ) AS u;';
    
    EXECUTE(@query);
    

    【讨论】:

    • 我不知道列名!请检查我的代码,我已经编辑了问题
    • 感谢您的回复我现在正在使用 unpivot 但是我似乎无法将所有列转换为特定类型。我收到以下错误:“Id”列的类型与 UNPIVOT 列表中指定的其他列的类型冲突。
    • @JamesDayeh ID 在哪里我看不到它,将其转换为与其他列相同类型的varchar 例如:CAST(Id AS VARCHAR(50))
    • @JamesDayeh - 正如我所说,您必须将所有列转换为相同的数据类型,请参阅this updated sql fiddle demo
    • @JamesDayeh - 如果您只想要列的名称,为什么不直接这样做:SELECT distinct QUOTENAME(column_name) FROM information_schema.columns WHERE table_name = 'Vehicles' 就像在 this fiddle demo 中一样
    【解决方案2】:

    我相信你想要这个

    Select Col1 + Col2 + Col3 + Col4 + Col5 From Table
    

    或者可能会关注

    Select Col1 From Table1
     union Select Col2 From Table1 
     union Select Col3 From Table1
     union Select Col4 From Table1 
     union Select Col5 From Table1 ;
    

    【讨论】:

    • 所以你的答案对吗?如果是,请在回答部分发布并接受
    猜你喜欢
    • 1970-01-01
    • 2013-03-31
    • 2016-02-25
    • 2013-07-02
    • 1970-01-01
    • 2019-05-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多