Mam zapytanie, które zwraca średnią (cenę)
select avg(price)
from(
select *, cume_dist() OVER (ORDER BY price desc) from web_price_scan
where listing_Type='AARM'
and u_kbalikepartnumbers_id = 1000307
and (EXTRACT(Day FROM (Now()-dateEnded)))*24 < 48
and price>( select avg(price)* 0.50
from(select *, cume_dist() OVER (ORDER BY price desc)
from web_price_scan
where listing_Type='AARM'
and u_kbalikepartnumbers_id = 1000307
and (EXTRACT(Day FROM (Now()-dateEnded)))*24 < 48
)g
where cume_dist < 0.50
)
and price<( select avg(price)*2
from( select *, cume_dist() OVER (ORDER BY price desc)
from web_price_scan
where listing_Type='AARM'
and u_kbalikepartnumbers_id = 1000307
and (EXTRACT(Day FROM (Now()-dateEnded)))*24 < 48
)d
where cume_dist < 0.50)
)s
having count(*) > 5
jak sprawić, by zwracał 0, jeśli żadna wartość nie jest dostępna?
sql
postgresql
Andrzej
źródło
źródło
from web_price_scan
to oddzielne wybory; nie wiesz, o co tu chodzi?having
klauzuli bezgroup by
(co domyślnie dotyczy pojedynczej grupy). Działa jakowhere
klauzula dotycząca wyników zagregowanych. W takim przypadku wiersze są zwracane tylko wtedy, gdy podzapytanie pierwszego poziomu zwraca więcej niż 5 wierszy.Odpowiedzi:
użyj coalesce
Edytować
Oto przykład
COALESCE
zapytania:COALESCE
Nie należy używać IMHO z,AVG
ponieważ modyfikuje wartość.NULL
oznacza nieznane i nic więcej. To nie jest jak używanie go wSUM
. W tym przykładzie, jeśli zastąpimyAVG
przezSUM
, wynik nie jest zniekształcony. Dodanie 0 do sumy nikomu nie zaszkodzi, ale obliczenie średniej z 0 dla nieznanych wartości, nie otrzymasz prawdziwej średniej.W takim przypadku dodałbym
price IS NOT NULL
wWHERE
klauzuli, aby uniknąć tych nieznanych wartości.źródło
from web_price_scan...
wydaje się powtarzać ...NULLIF(v1, v2)
robi coś zupełnie przeciwnegoCOALESCE
, ponieważ zwraca,NULL
jeśliv1
jest równev2
.(ta odpowiedź została dodana, aby przedstawić krótsze i bardziej ogólne przykłady pytania - bez uwzględniania wszystkich szczegółów dotyczących konkretnego przypadku w pierwotnym pytaniu).
Występują tutaj dwa różne „problemy”, pierwszy dotyczy sytuacji, w której tabela lub podzapytanie nie ma wierszy, a drugi dotyczy wartości NULL w zapytaniu.
We wszystkich testowanych wersjach postgres i mysql ignorują wszystkie wartości NULL podczas uśredniania i zwracają NULL, jeśli nie ma nic do uśrednienia. Generalnie ma to sens, ponieważ NULL należy uważać za „nieznane”. Jeśli chcesz to zmienić, możesz użyć coalesce (zgodnie z sugestią Luca M).
oczywiście "from foo" można zastąpić "from (... tutaj dowolna skomplikowana logika ...) as foo"
Czy teraz wiersz NULL w tabeli powinien być liczony jako 0? Następnie coalesce musi być użyte w wywołaniu avg.
źródło
Przychodzą mi do głowy 2 sposoby, aby to osiągnąć:
IFNULL ():
Funkcja IFNULL () zwraca określoną wartość, jeśli wyrażenie ma wartość NULL. Jeśli wyrażenie NIE ma wartości NULL, ta funkcja zwraca wyrażenie.
Składnia:
Przykład IFNULL () w zapytaniu:
ŁĄCZYĆ()
Funkcja COALESCE () zwraca pierwszą wartość różną od null na liście.
Składnia:
Przykład COALESCE () z zapytaniem:
źródło