SQL 中的行到列,反之亦然

Rows to Columns and viceversa in SQL

我是 sql 的新手,我需要一种更好的方法来应对以下情况。

Table

我需要转换成下面的结果。

对每个 coln 做一个 UNION ALL,一个 select,最后对没有任何 yes 的行做一个 SELECT。

select id, 'col1' from tablename where col1 = 'yes'
union all
select id, 'col2' from tablename where col2 = 'yes'
union all
select id, 'col3' from tablename where col3 = 'yes'
union all
select id, 'col4' from tablename where col4 = 'yes'
union all
select id, cast(null as char(4)) from tablename
    where 'yes' not in (coalesce(col1, 'x'),
                        coalesce(col2, 'x'),
                        coalesce(col3, 'x'),
                        coalesce(col4, 'x'))

如果唯一的值是'yes'(或NULL),那么最后的select可以做成

select id, cast(null as char(4)) from tablename
where coalesce(col1, col2, col3, col4) is null

另外,您也可以按照下面的方式进行。

;WITH CTE
AS
(
    SELECT 
       B.ID, 
       B.yes,
       B.col
    FROM 
        (SELECT ID ,
                ISNULL(COL1, '') COL1 ,
                ISNULL(COL2, '') COL2,
                ISNULL(COL3, '') COL3 ,
                ISNULL(COL4, '') COL4
            FROM @Tbl) A
    UNPIVOT
    (
      col
      FOR yes in (col1, col2, col3, col4)
    ) B
) 


SELECT CTE.ID, CTE.yes FROM  CTE
WHERE  col = 'yes'
UNION ALL
SELECT DISTINCT  ID, '' FROM CTE A
WHERE NOT EXISTS
(
    SELECT 1 FROM CTE B WHERE 
        B.ID = A.ID AND
        B.col = 'yes'
)

结果:

ID          yes  
----------- -----
1           COL1
1           COL3
2           COL2
2           COL4
3           COL3
4           
5           COL2
5           COL3
6           
7           COL4

您可以尝试使用 unpivot。这是带有数据的示例演示。

DECLARE @Table TABLE (
        ID INT
        ,COL1 VARCHAR(3)
        ,COL2 VARCHAR(3)
        ,COL3 VARCHAR(3)
        ,COL4 VARCHAR(3)
        )
INSERT INTO @TABLE VALUES

(1,'yes',null,'yes',null)
,(2,null,'yes',null,'yes')
,(3,null,null,'yes',null)
,(4,null,null,null,null)
,(5,null,'yes','yes',null)
,(6,null,null,null,null)
,(7,null,null,null,'yes')


SELECT id
    ,yes
FROM (
    SELECT id
        ,col1
        ,col2
        ,col3
        ,col4
    FROM @TABLE
     where coalesce(col1, col2, col3, col4) is not null
    ) AS cp
UNPIVOT(yes FOR col IN (
            col1
            ,col2
            ,col3
            ,col4
            )) AS up
union
select id, null from @TABLE
    where coalesce(col1, col2, col3, col4) is null
order by id