2013-10-22 2 views
13

같은 종류의 데이터를 포함하는 9 개의 열을 포함하는 테이블을 데이터베이스에 가지고 있는데이 값은 이 null 인 허용입니다. Null이 아닌 각 값을 원래 열의 ID에 상관하지 않는 단일 값 열로 선택해야합니다.여러 열의 값을 하나의 열로 선택

그래서,이처럼 보이는 테이블 :

+---------+------+--------+------+ 
| 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로 시작 각각의 값을 선택하고 싶습니다. 결과 데이터는 다음 표와 같아야합니다. 순서는 유지해야하므로 첫 번째 행의 첫 번째 열 값은 상단과 하단에있는 마지막 행의 마지막 열 값에 있어야합니다 : 나는 SQL Server 2008을 사용하고

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

R2 . 각 열의 값을 차례대로 선택하고 결과에 null이 아닌 값을 삽입하는 것보다 더 나은 방법이 있습니까?

답변

17

당신은 최종 결과를 얻기 위해 UNPIVOT 기능을 사용할 수 있습니다

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

당신은 SQL 서버 2008+, 다음 수를 사용하고 있기 때문에 VALUES 절과 함께 CROSS APPLY를 사용하여 열을 unpivot하십시오.

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 
+8

여기서 주목해야 할 중요한 점은 [현재 가장 많이 투표 된 답변] (http://stackoverflow.com/a/19515927/61305)과 달리 전체 테이블 스캔 횟수가 최소화된다는 것입니다 (1 vs. 3). 그리고 5 열 또는 8 열 또는 22 열이 있으면 둘 다 해당 수에 대한 스캔 수를 늘리고 쿼리의 UNION 버전을 쓰거나 볼 때 훨씬 성가 시게 만듭니다. –

5
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

시도 조합 아래 같은 :

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 
관련 문제