2013-07-24 24 views
23

Mam kwerendy wewnątrz procedury składowanej, która podsumowuje pewne wartości wewnątrz tabeli:zwróci zero, jeśli nie znaleziono rekordu

SELECT SUM(columnA) FROM my_table WHERE columnB = 1 INTO res; 

Następnie wybierz odjąć res wartości z całkowitą odzyskane przez innego zapytania i powrót wynik. Jeśli zostanie sprawdzona klauzula WHERE, wszystko działa poprawnie. Ale jeśli tak nie jest, cała moja funkcja zwraca pustą kolumnę (może dlatego, że próbuję odjąć liczbę całkowitą z pustą wartością).

W jaki sposób sprawić, aby zapytanie zwróciło zero, jeśli klauzula WHERE nie jest spełniona?

+0

'INTO var' załączonym do' 'SELECT ... jest ważna tylko w kodzie PL/PGSQL, a nie zwykły SQL . Zakładam, że jest to część funkcji PL/pgSQL lub instrukcji 'DO'. Poprawny? –

Odpowiedz

46

Mogłabyś:

SELECT COALESCE(SUM(columnA), 0) FROM my_table WHERE columnB = 1 INTO res; 

Dzieje się tak do pracy, ponieważ zapytanie ma funkcję kruszywa iw konsekwencji zawsze zwraca wiersz, nawet jeśli nie znajduje się w tabeli podstawowej.

Zwykłe zapytania bez agregatu zwrócą w takim przypadku bez wiersza. COALESCE nigdy nie zostanie wywołany i nie może cię uratować. Natomiast do czynienia z jednej kolumnie możemy owinąć całą zapytania zamiast:

SELECT COALESCE((SELECT columnA FROM my_table WHERE ID = 1), 0) 
INTO res; 

pracuje dla pierwotnym zapytaniu także:

SELECT COALESCE((SELECT SUM(columnA) FROM my_table WHERE columnB = 1), 0) 
INTO res; 

Więcej o COALESCE() in the manual.
Więcej o aggregate functions in the manual.
Więcej alternatywy w tym późniejszym postu:

+1

@FreshPrinceOfSO: Myślę, że należy zauważyć, że 'COALESCE' jest * standardem * SQL to zrobić. –

+0

Miałem [złe doświadczenie] (http://dba.stackexchange.com/questions/46486/function-hangs-with-null-case-operation) z 'COALESCE' ... Powiedzmy, że nie jesteśmy przyjaciółmi już. – Kermit

+3

@FreshPrinceOfSO To jest bardziej 'Miałem złe doświadczenia z SQL Server' wtedy' Miałem złe doświadczenia z COALESCE'. Nie ma nic złego w 'COALESCE' w innych RDBMS. –

1

nie jestem zaznajomiony z PostgreSQL, ale w SQL Server lub Oracle, za pomocą podzapytania będzie działać jak poniżej (w Oracle, SELECT 0 byłoby SELECT 0 FROM DUAL)

SELECT SUM(sub.value) 
FROM 
( 
    SELECT SUM(columnA) as value FROM my_table 
    WHERE columnB = 1 
    UNION 
    SELECT 0 as value 
) sub 

Może to będzie działać dla PostgreSQL zbyt?

0

Można też spróbować: (próbowałem tego i pracował dla mnie)

SELECT ISNULL((SELECT SUM(columnA) FROM my_table WHERE columnB = 1),0)) INTO res;