2014-04-23 3 views
6

테이블을 unpivot 할 수는 있지만 null 값은 결과에 포함되지 않습니다.UNPIVOT에서 NULL 값을 처리하십시오.

create table pivot_task 
(
age int null, 
[a] numeric(8,2), 
[b] numeric(8,2), 
[c] numeric(8,2), 
[d] numeric(8,2), 
[e] numeric(8,2) 
); 

select * from pivot_task; 

insert into pivot_task values (18, 0.5, null, 0.6, 1.21, 1.52), 
(19, 7.51, 6.51, 5.51, null, 3.53), 
(20, 4.52, 4.52, 6.52, 3.53, null); 


select age, [over], [av] 
from pivot_task 
unpivot 
(
[av] 
for [over] in ([a], [b], [c], [d], [e]) 
) a; 

당신은 18 세 [이상] B와 null 값은 내가 모든 널 상대를 위해서뿐만 아니라 널 (null)을 포함 할 행방 불명에 대한 http://sqlfiddle.com/#!6/2ab59/1에 결과를 볼 수 있습니다.

다른 값으로 null을 대체 한 다음 이러한 모든 상수 값 접근 방식을 바꾸는 것이 내 작업에 적합하지 않습니다. 피벗에만 포함시키고 싶습니다.

+2

'18 세 이상'? 여기에는 특히 그래픽 또는 폭력적인 SQL이 포함되어 있습니까? – Paul

+0

@Westie pivot_task 테이블에서 널값을 다른 값으로 바꾸고 unpivot으로 바꾸지 만 소스 테이블 pivot_task를 수정할 수 없습니까? –

+1

숫자가 지정된 범위에 속하면 (음수가 아님)이 문제를 해결할 수 있습니다. 올바른 형식의 질문은 +1. –

답변

4

이 못생긴하지만 NULL에 대한 대역 교체를 찾을 필요에 의존하지 않습니다

declare @pivot_task table 
(
age int null, 
[a] numeric(8,2), 
[b] numeric(8,2), 
[c] numeric(8,2), 
[d] numeric(8,2), 
[e] numeric(8,2) 
); 

insert into @pivot_task values (18, 0.5, null, 0.6, 1.21, 1.52), 
(19, 7.51, 6.51, 5.51, null, 3.53), 
(20, 4.52, 4.52, 6.52, 3.53, null); 


select a.age, pmu.[over], [av] 
from (select 'a' as [over] union all select 'b' union all select 'c' 
     union all select 'd' union all select 'e') pmu 
cross join (select age from @pivot_task) as a 
left join 
@pivot_task pt 
unpivot 
(
[av] 
for [over] in ([a], [b], [c], [d], [e]) 
) ex 
on pmu.[over] = ex.[over] and 
    a.age = ex.age 

결과 :

age   over av 
----------- ---- --------------------------------------- 
18   a 0.50 
18   b NULL 
18   c 0.60 
18   d 1.21 
18   e 1.52 
19   a 7.51 
19   b 6.51 
19   c 5.51 
19   d NULL 
19   e 3.53 
20   a 4.52 
20   b 4.52 
20   c 6.52 
20   d 3.53 
20   e NULL 

하지만 추락하는 경우이 경로를 사용하면 전체적으로 UNPIVOT을 제거 할 수 있습니다.

select a.age, pmu.[over], 
     CASE pmu.[over] 
      WHEN 'a' THEN a.a 
      WHEN 'b' THEN a.b 
      WHEN 'c' THEN a.c 
      WHEN 'd' THEN a.d 
      WHEN 'e' THEN a.e 
     END [av] 
from (select 'a' as [over] union all select 'b' union all select 'c' 
     union all select 'd' union all select 'e') pmu 
cross join @pivot_task as a 
+0

예 UNPIVOT을 완전히 제거한 두 번째 쿼리가 있지만이 쿼리의 작동 방식을 조금 설명하면 되겠습니까? –

+1

'CROSS JOIN'은 왼쪽 테이블의 모든 행과 오른쪽 테이블의 모든 행을 쌍으로 만듭니다. 이 경우, 왼쪽 테이블은'a' -'e'를 포함하는 5 행의 집합이고, 오른쪽 테이블은 원래의'pivot_task' 테이블입니다. 그래서 우리는'a' -'e','19' 행은'a' -'e'와 짝을 이루는 나이'18' 행으로 끝납니다 ... 그리고 나서'CASE' 표현에서, 'pivot_task' 행이 현재 페어링 된 문자와 일치하는 열을 선택하기 만하면됩니다. –

3

이 방법을 사용해보십시오. 숫자 (8,2)에서 허용되지 않는 숫자가 아닌 unpivot 전에 10000000의 null 값이 있으므로 값이 이미 존재하지 않습니다. 그 값이 널 UNPIVOT 후 교체 될 것이다

;WITH x as 
(
select 
age, 
coalesce(cast(a as numeric(9,2)), 10000000) a, 
coalesce(cast(b as numeric(9,2)), 10000000) b, 
coalesce(cast(c as numeric(9,2)), 10000000) c, 
coalesce(cast(d as numeric(9,2)), 10000000) d, 
coalesce(cast(e as numeric(9,2)), 10000000) e 
from pivot_task 
) 
select age, [over], nullif([av], 10000000) av 
from x 
unpivot 
(
[av] 
for [over] in ([a], [b], [c], [d], [e]) 
) a; 
1

사용 ISNULL (기둥 이름, 0) UNPIVOT IT BEFORE ALL FOR COLUMN http://technet.microsoft.com/en-us/library/ms184325.aspx.

아래와 같습니다.

Select Age, Data, Case When (Value = 0) Then NULL Else Value End Value 
from (
select age, 
    ISNULL([a],0)[a], ISNULL([b],0)[b], ISNULL([c],0)[c], ISNULL([d],0)[d], ISNULL([e],0)[e] 
From pivot_task) As pvttask 
UnPivot ([Value] for [Data] In ([a], [b], [c], [d], [e])) a 
+0

은 기본적으로 @VigneshKumar가 게시 한 것과 같은 대답이 아니십니까? –