2009-02-26 24 views
23

Chcę dodać dwie liczby razem, ale gdy jedna z tych liczb jest zerowa, wynik jest zerowy. Czy istnieje sposób obejścia tego. Mogę po prostu zrobić to w kodzie, ale wolałbym, żeby to było zrobione w zapytaniu. To jest baza danych Oracle.Suma kolumn z wartościami pustymi w Oracle

Struktura tabeli

hours_t 
type  craft regular  overtime 
A   1  5    0 
A   1  3    1 
B   2  9   <null> 
B   1  4    4 

W zapytaniu

select type, craft, sum(regular + overtime) as total_hours 
from hours_t 
group by type, craft 
order by type, craft 

niepożądanych skutków

type craft total_hours 
    A  1   9 
    B  1   8 
    B  2  <null> 

Pożądane rezultaty

type craft total_hours 
    A  1   9 
    B  1   8 
    B  2   9 
+1

Według sposób, proszę, nie usuwaj swoich komentarzy, jeśli podano odpowiedź;) –

+0

usunąłem komentarz, ponieważ odpowiedź została zmieniona. –

Odpowiedz

44
select type, craft, sum(nvl(regular,0) + nvl(overtime,0)) as total_hours 
from hours_t 
group by type, craft 
order by type, craft 
0
select type, craft, sum(NVL(regular, 0) + NVL(overtime, 0)) as total_hours 
from hours_t 
group by type, craft 
order by type, craft 
46

NVL (wartość domyślna) jest funkcją szukasz.

select type, craft, sum(NVL(regular, 0) + NVL(overtime, 0)) as total_hours 
from hours_t 
group by type, craft 
order by type, craft 

Oracle ma 5 związanych NULL funkcje:

  1. nvl
  2. NVL2
  3. COALESCE
  4. NULLIF
  5. LNNVL

NVL:

NVL(expr1, expr2) 

NVL pozwala zastąpić puste (zwracany jako puste) z ciągiem w wynikach kwerendy. Jeśli wyrażenie1 ma wartość null, to NVL zwraca wyrażenie2. Jeśli wyrażenie1 nie ma wartości null, to NVL zwraca wyrażenie1.

NVL2:

NVL2(expr1, expr2, expr3) 

NVL2 pozwala określić wartość zwróconego przez kwerendę na podstawie tego, czy określone wyrażenie jest null lub nie jest pusta. Jeśli wyrażenie1 nie jest puste, to NVL2 zwraca wyrażenie2. Jeśli wyrażenie1 ma wartość null, to NVL2 zwraca wyrażenie3.

COALESCE

COALESCE(expr1, expr2, ...) 

COALESCE zwraca pierwszy niezerowym expr na liście ekspresji. Przynajmniej jedno wyrażenie nie może być literałem NULL. Jeśli wszystkie wystąpienia expr zostaną ocenione jako null, funkcja zwróci wartość null.

NULLIF

NULLIF(expr1, expr2) 

NULLIF porównuje wyrażenie wyrażenie1 i wyrażenie2. Jeśli są równe, funkcja zwraca wartość null. Jeśli nie są równe, funkcja zwraca wartość wyraż1. Nie można podać literalnej wartości NULL dla wyraż1.

LNNVL

LNNVL(condition) 

LNNVL zawiera zwięzły sposób oceny stanu, gdy jeden lub oba operandy tego warunku może być null.

Więcej informacji na Oracle SQL Functions

+0

Mogłeś rzucić w CASE i DECODE o kompletność;) –

1

trzeba użyć funkcji NVL, np

SUM (NVL (regularne, 0) + NVL (nadgodziny, 0))

9

innych odpowiedzi dotyczących korzystania z NVL() są poprawne, jednak żaden wydają się zająć bardziej wysunięty punkt:

Czy w tej kolumnie masz nawet wartości NULL?

Czy mają one znaczenie inne niż 0?

Wydaje się to przypadku należy mieć NOT NULL default 0 na th ecolumn

+0

Pierwszym celem SO powinno być odpowiedź na PO. Programiści mają potrzebę. Tą potrzebą jest odpowiedzieć na pytanie. Czy wiesz nawet, czy BerekBryan ma możliwość zmiany kolumny? Czy nawet spotkał osobę, która może to zmienić? Wiem, że wszyscy chcemy pokazać, jak bardzo jesteśmy mądrzy, ale trzymajmy się OP –

+2

@ Mark Brady, naprawdę nie zgadzam się. Nie jest to "jak mądry jesteśmy", ale raczej sugeruje alternatywne sposoby podejścia do problemu. OP może, ale nie musi mieć możliwość zmiany kolumny, ale komentarz jest przydatny (jeśli nie dla niego, to prawdopodobnie dla innych, którzy czytają ten wątek). –

+2

@cletus, myślę, że jest to bardziej odpowiednie jako komentarz do pytania niż oddzielnej odpowiedzi. –

4

najwyższej klasy odpowiedź z NVL jest całkowicie prawidłowy. Jeśli masz jakieś zainteresowania w tworzeniu kodu SQL bardziej przenośne, można użyć Case, który jest obsługiwany z taką samą składnię zarówno Oracle i SQL Server:

select 
    type,craft, 
    SUM(
    case when regular is null 
     then 0 
     else regular 
    end 
    + 
    case when overtime is null 
     then 0 
     else overtime 
    end 
) as total_hours 
from 
    hours_t 
group by 
    type 
,craft 
order by 
    type 
,craft 
0

Kod:

select type, craft, sum(coalesce(regular + overtime, regular, overtime)) as total_hours 
from hours_t 
group by type, craft 
order by type, craft 
+0

Pomaga, jeśli trochę sformatowałeś kod i wyjaśniłeś, co robi dla osób zainteresowanych wiedzą, jak działa twoja odpowiedź – ochi

Powiązane problemy