从多列中选择值到单列

时间:2013-10-22 10:52:13

标签: sql sql-server sql-server-2008-r2 unpivot

我在数据库中有一个表,其中有9列包含相同类型的数据,这些值允许为空。我需要将每个非空值选择到一列值中,这些值不关心它们所源自的行的标识。

所以,对于一个看起来像这样的表:

+---------+------+--------+------+
|   Id    | I1   | I2     | I3   | 
+---------+------+--------+------+
|    1    | x1   | x2     |  x7  |
|    2    | x3   | null   |  x8  |
|    3    | null | null   |  null|
|    4    | x4   | x5     |  null|
|    5    | null | x6     |  x9  |
+---------+------+--------+------+

我希望将每个以x为前缀的值选择为单个列。我的结果数据应如下表所示。需要保留订单,因此第一行的第一列值应位于顶部,最后一列的值应位于底部的最后一行:

+-------+
| value |
+-------+
|  x1   |
|  x2   |
|  x7   |
|  x3   |
|  x8   |
|  x4   |
|  x5   |
|  x6   |
|  x9   |
+-------+

我正在使用 SQL Server 2008 R2 。是否有更好的技术来实现这一点,而不是从每一行依次选择每列的值,并将非空值插入结果?

3 个答案:

答案 0 :(得分:18)

您可以使用UNPIVOT函数获取最终结果:

select value
from yourtable
unpivot
(
  value
  for col in (I1, I2, I3)
) un
order by id, col;

由于您使用的是SQL Server 2008+,因此您还可以使用带有VALUES子句的CROSS APPLY来取消列:

select value
from yourtable
cross apply
(
    values
        ('I1', I1),
        ('I2', I2),
        ('I3', I3)
) c(col, value)
where value is not null
order by id, col

答案 1 :(得分:6)

SELECT value FROM (
   SELECT ID, 1 AS col, I1 AS [value] FROM t
   UNION ALL SELECT ID, 2,  I2 FROM t
   UNION ALL SELECT ID, 3,  I3 FROM t
) AS t WHERE value IS NOT NULL ORDER BY ID, col;

答案 2 :(得分:4)

尝试下面的联盟:

    select value from
(
    select col1 as value from TestTable
    union
    select col2 as value from TestTable
    union
    select col3 as value from TestTable
) tt where value is not null