sql-将多列(不同数据类型)转换为一列(每一列一行)

时间:2019-01-16 18:15:52

标签: sql-server

我试图将具有不同数据类型的多列转换为一列(一列一行),所有列都将转换为varchar。

我要转换的表格:

+----+----------------+-------------------------+------------+------------+
| id | column_varchar |     column_datetime     | column_int | column_bit |
+====+================+============+==========+===========+===========+===+
| 1  |      NULL      |           NULL          |     NULL   |     1      |
+----+----------------+-----------------+------------+------------+-------+
| 2  |      NULL      | 2019-01-15 00:00:00.000 |     NULL   |    NULL    |
+----+----------------+-------------------------+------------+------------+  
| 3  |      apple     |           NULL          |     NULL   |    NULL    |
+----+----------------+---------------------+------------+------------+---+
| 4  |      NULL      |           NULL          |     NULL   |     0      |
+----+----------------+---------------------+------------+------------+---+
| 5  |      NULL      | 2018-01-15 00:00:00.000 |     NULL   |    NULL    |
+----+----------------+---------------------+------------+------------+---+
| 6  |      NULL      |           NULL          |     25     |    NULL    |
+----+----------------+---------------------+------------+------------+---+

我需要创建一个单列,其中包含所有列的值(广播到varchar)及其各自的键值,我希望这样:

+----+-------------------------+
| id |        column_value     |
+====+=========================+
|  1 |              1          |
+----+-------------------------+
|  2 | 2019-01-15 00:00:00.000 |
+----+-------------------------+
|  3 |           apple         |
+----+-------------------------+
|  4 |            0            |
+----+-------------------------+
|  5 | 2018-01-15 00:00:00.000 |
+----+-------------------------+
|  6 |           25            |
+----+-------------------------+

如何使用SQL-Server完成此任务?谢谢

4 个答案:

答案 0 :(得分:2)

使用合并:

Select id,coalesce
             (
               cv,
               Cast(cd As VarChar(50)),
               Cast(ci As VarChar(50)),
               Cast(cb As VarChar(50))
             ) As ColVal
From #tbl

结果:

id  ColVal
1   1
2   Jan 15 2019 12:00AM
3   Apple
4   0
5   Jan 15 2019 12:00AM
6   25

答案 1 :(得分:1)

这里是一个选项,它使用一点XML与CROSS APPLY(或两个)一起使用

其他选项可能更有效,但是这里的好处是它实际上将消耗任何表,视图或查询,而无需指定列。

示例

Select A.ID 
      ,C.*
 From YourTable A
 Cross Apply (values (convert(xml,(Select A.* for XML RAW)))) B(XMLData)
 Cross Apply (
                Select Item  = xAttr.value('local-name(.)', 'varchar(100)')
                      ,Value = xAttr.value('.','varchar(max)')
                 From  XMLData.nodes('//@*') xNode(xAttr)
             ) C
 Where Item not in ('ID')

返回

ID  Item              Value
1   column_bit        1
2   column_datetime   2019-01-15T00:00:00
3   column_varchar    apple
4   column_bit        0
5   column_datetime   2019-01-15T00:00:00
6   column_int        25

答案 2 :(得分:0)

请执行以下操作:

SELECT
   id
  ,column_varchar  column_value  --  Column alias in only needs to be set in the first select
 from MyTable
 where column_varchar is not null
UNION ALL SELECT
   id
  ,convert(varchar(50), column_datetime, 121)
 from MyTable
 where column_datetime is not null
UNION ALL SELECT
   id
  ,cast(column_int as (varchar(50))
 from MyTable
 where column_int is not null
UNION ALL SELECT
   id
  ,cast(column_bit as (varchar(50))
 from MyTable
 where column_bit is not null

(仅出于很多原因,这样做可能不是一个好主意。)

答案 3 :(得分:0)

如果每行仅 ONE 个值,则可以使用concat()

您可能会注意到我在datetime列上进行了一次转换以保持格式。

示例

Select A.ID
      ,column_value = concat([column_varchar],convert(varchar(25),[column_datetime],25),[column_int],[column_bit])
 From  YourTable A

返回

1   1
2   2019-01-15 00:00:00.000
3   apple
4   0
5   2019-01-15 00:00:00.000
6   25