SQL行为2列

时间:2012-03-28 22:20:16

标签: sql sql-server

我有一个包含A,B,C,D,E,F列的数据行... 我怎么能写一个sql select来得到结果:

Col1, Col2
A,    B
C,    D
E,    F
...

编辑: 只有一行和动态列数。我不允许使用information_schema和sys表。同样有趣的是知道如何为整个表(多个A,B,C,D,E ..行),而不是唯一的行。

4 个答案:

答案 0 :(得分:5)

如果您提前知道列的列表,那么它应该像将两个列的每个组合并在一起一样简单:

;with Data as (
    select 'A' as A, 'B' as B, 'C' as C, 'D' as D, 'E' as E, 'F' as F
)
select A,B from Data union
select C,D from Data union
select E,F from Data

如果列列表是动态的,则需要动态SQL进行处理。这是一个使用包含11列的测试表的完整工作示例:

create table Test (id01 int,id02 int,id03 int,id04 int,id05 int,id06 int,id07 int,id08 int,id09 int,id10 int,id11 int);
insert Test values (1,2,3,4,5,6,7,8,9,10,11);

declare @select varchar(max)
;with ColumnInfo as (
    select
        row_number() over (order by column_name) - 1 as rownumber,
        column_name
    from information_schema.columns
    where table_name = 'Test'
)
select
    @select = coalesce(@select + ' union ' + char(13) + char(10), '') +
        'select ' + max(case when rownumber % 2 = 0 then column_name end) +
        ',' + coalesce(max(case when rownumber % 2 = 1 then column_name end), 'NULL') +
        ' from test'
from
    ColumnInfo
group by
    rownumber / 2

exec(@select)

示例输入:

id01 id02 id03 id04 id05 id06 id07 id08 id09 id10 id11
1    2    3    4    5    6    7    8    9    10    11

示例输出:

id01 id02
1    2
3    4
5    6
7    8
9    10
11   NULL

现场演示:http://sqlfiddle.com/#!3/d0507/1

答案 1 :(得分:4)

使用unpivot你可以这样做。 See it working

WITH piv1 
     AS (SELECT foo, 
                bar, 
                Row_number() OVER (ORDER BY bar) rn 
         FROM   test p 
                UNPIVOT (foo FOR bar IN (col1, col2, col3, col4, col5, col6) ) 
                AS unpvt) 
SELECT t1.foo col1, 
       t2.foo col2 
FROM   piv1 t1 
       INNER JOIN piv1 t2 
         ON t1.rn = t2.rn - 1 
WHERE  t1.rn % 2 = 1 

如果你想让它变得动态,你只需要使这部分动态

UNPIVOT (foo FOR bar IN (col1, col2, col3, col4, col5, col6) )

答案 2 :(得分:1)

使用MS SQL,你可以使用这个技巧:

DECLARE @s VARCHAR(max)

SET @s=''

SELECT @s=@s+','+val FROM (
SELECT Col1 AS [val] FROM [your table]
UNION ALL 
SELECT Col2 FROM [your table] ) as [data]
ORDER BY [val]
SELECT @s

使用PostgreSQL:

SELECT string_agg( "val",',') FROM (
SELECT Col1 AS "val" FROM "your table"
UNION ALL 
SELECT Col2 FROM "your table"
ORDER BY 1 ) AS "data"

MySQL的:

SELECT GROUP_CONCAT( `val`,',') FROM (
SELECT Col1 AS `val` FROM `your table`
UNION ALL 
SELECT Col2 FROM `your table`
ORDER BY 1 ) AS `data`;

答案 3 :(得分:1)

如果您希望显示列名(而不是取消忽略一行的数据),您可以使用information_schema

SELECT a.column_name AS col1
     , b.column_name AS col2
FROM 
    information_schema.columns AS a
  LEFT JOIN
    information_schema.columns AS b
        ON  b.table_schema = 'database_name'
        AND b.table_name = 'table_name' 
        AND b.ordinal_position = a.ordinal_position + 1
WHERE a.table_schema = 'database_name'
  AND a.table_name = 'table_name'  
  AND a.ordinal_position % 2 = 1 ;