SQL列到行的转换

时间:2009-12-11 05:46:26

标签: sql database pivot

我有一个具有以下结构的表:

Col1    Col2
---------------
1        2    
3        4

我需要以这样的方式查询输出应该是:

ColumnName |  ColumnValue
----------------------------
Col1          1
Col2          2
Col1          3
Col2          4

非常感谢任何帮助。 提前谢谢。

3 个答案:

答案 0 :(得分:5)

已经澄清了必须对输出进行排序,使其在col1和col2之间交替。即使col2的值较低,也始终首先显示Col1。这样:

Col1  |  Col2 
------------
11    |  2 
30    |  42 

..应该返回:

ColumnName  |  ColumnValue
----------------------------
col1        |  11 
col2        |  2 
col1        |  30 
col2        |  42

有效地,基于排名的交替列表。

目前尚不清楚OP正在使用哪个数据库。假设MySQL没有排名/分析功能,您可以使用:

  SELECT x.* 
    FROM (SELECT 'Col1' AS ColumnName,
                 a.col1 AS ColumnValue,
                 @rowcol1 := @rowcol1 + 1 AS rank
            FROM TABLE a
            JOIN (SELECT @rowcol1 := 0) r
          UNION ALL
          SELECT 'Col2',
                 b.col2,
                 @rownum := @rownum + 1
            FROM TABLE b
            JOIN (SELECT @rownum := 0) r) x
ORDER BY x.rank, x.columnname

SQL Server 2005+和Oracle 9i +支持分析功能,因此您可以使用ROW_NUMBER或RANK:

  SELECT x.* 
    FROM (SELECT 'Col1' AS ColumnName,
                 a.col1 AS ColumnValue,
                 ROW_NUMBER() OVER(ORDER BY a.col1) AS rank
            FROM TABLE a
          UNION ALL
          SELECT 'Col2',
                 b.col2,
                 ROW_NUMBER() OVER(ORDER BY b.col2) AS rank
            FROM TABLE b) x
ORDER BY x.rank, x.columnname

以前,根据提供的示例数据:

SELECT 'Col1' AS ColumnName, 
       a.col1 AS ColumnValue
  FROM TABLE a
UNION ALL
SELECT 'Col2', 
       b.col2
  FROM TABLE b
ORDER BY ColumnValue

UNION ALL会返回所有行,而UNION会删除重复项。

答案 1 :(得分:1)

您还可以尝试UNPIVOT

DECLARE @Table TABLE(
        Col1 INT,
        Col2 INT 
)

INSERT INTO @Table SELECT 1,2
INSERT INTO @Table SELECT 3,4

SELECT ColumnName, ColumnValue
FROM    (
            SELECT Col1, Col2
            FROM    @Table
        ) p
UNPIVOT
    (
        ColumnValue FOR ColumnName IN (Col1, Col2)
    ) upvt

答案 2 :(得分:0)

修复了OMG解决方案的订购问题:

SELECT 'Col1' AS ColumnName, 
       a.col1 AS ColumnValue
  FROM TABLE a
UNION ALL
SELECT 'Col2', 
       b.col2
  FROM TABLE b
ORDER BY ColumnName, ColumnValue