2014-04-23 7 views
6

Ich kann eine Tabelle deaktivieren, aber Null-Werte sind nicht im Ergebnis enthalten.Handle NULL-Wert in UNPIVOT

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; 

können Sie sehen das Ergebnis auf http://sqlfiddle.com/#!6/2ab59/1 18 Jahren [über] b und seiner Null-Wert fehlt ich null als auch für jede Null Begegnung aufnehmen möchten.

Ich fand, Null mit anderen Wert zu ersetzen und dann alle diese Konstanten unterschiedlichen Wert Ansatz ersetzen ist nicht machbar für meine Arbeit. Ich möchte nur in Unpivot aufnehmen.

+2

'Für 18 Jahre [über]'? Enthält dies besonders grafische oder gewalttätige SQL? – Paul

+0

@Westie Sagen Sie in pivot_task Tabelle Null-Wert durch andere ersetzen, dann pivot, aber ich kann die Quellentabelle pivot_task nicht ändern. –

+1

Wenn Ihr numerischer Wert in den angegebenen Bereich gehört (sagt nicht-negativ), können Sie dieses Problem umgehen. +1 für wohlgeformte Frage. –

Antwort

4

Dies ist hässlich, aber beruht nicht auf, die einen Out-of-Band-Ersatz für NULL zu finden:

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 

Ergebnis:

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 

Aber wenn du gehst nach unten diesem Route, können Sie die UNPIVOT vollständig zu beseitigen:

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

yeah die 2. Abfrage, um den UNPIVOT zu eliminieren funktioniert völlig, aber würden Sie ein bisschen erklären, wie diese Abfrage funktioniert? –

+1

Ein 'CROSS JOIN' verbindet jede Reihe vom linken Tisch mit jeder Reihe vom rechten Tisch. In diesem Fall ist die linke Tabelle nur eine Gruppe von fünf Zeilen, die 'a' -' e' enthalten, und die rechte Tabelle ist Ihre ursprüngliche 'pivot_task'-Tabelle. Also enden wir mit der Zeile Alter 18, gepaart mit jedem von a - e, die Zeile 19 mit gepaart mit a - e, ... Dann im CASE-Ausdruck, Wir wählen einfach die Spalte aus, die mit dem Buchstaben übereinstimmt, mit dem die Zeile 'pivot_task' gerade gepaart ist. –

3

Versuchen Sie dies, wird es ersetzen lle die NULL-Werte mit 10000000 vor dem Unpivot, das ist keine akzeptable Zahl in numerischer (8,2), so dass der Wert nicht bereits existiert. Dann wird der Wert von null nach Entpivotisierung ersetzt:

;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

USE ISNULL (column, 0) http://technet.microsoft.com/en-us/library/ms184325.aspx für alle Spalten VOR UNPIVOT IT.

wie unten.

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

ist das nicht im Grunde die gleiche Antwort wie die von @VigneshKumar gepostet? –