postgresql возвращает 0, если возвращаемое значение равно null
У меня есть запрос, который возвращает avg (price)
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
Как заставить его вернуть 0, если значение не доступно?
2 ответа:
использовать коалесцируют
COALESCE(value [, ...])
The COALESCE function returns the first of its arguments that is not null. Null is returned only if all arguments are null. It is often used to substitute a default value for null values when data is retrieved for display.
изменить Вот пример объединения с вашим запросом:
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 COALESCE( price, 0 ) > ( SELECT AVG( COALESCE( price, 0 ) )* 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 COALESCE( price, 0 ) < ( SELECT AVG( COALESCE( price, 0 ) ) *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
ИМХО
COALESCE
не следует использовать сAVG
потому что оно изменяет значение.NULL
означает неизвестный и ничего больше. Это не похоже на использование его вSUM
. В этом примере, если мы заменимAVG
bySUM
, результат не искажен. Добавление 0 к сумме никому не повредит, но вычисление среднего значения с 0 для неизвестные значения, вы не получите реальное среднее значение.в таком случае, я бы добавил
price IS NOT NULL
наWHERE
п. Чтобы избежать этих неизвестных значений.
(этот ответ был добавлен, чтобы обеспечить более короткие и более общие примеры к вопросу - без включения всех конкретных деталей в исходном вопросе).
здесь есть две различные "проблемы", первая-если таблица или подзапрос не имеет строк, вторая-если в запросе есть нулевые значения.
для всех версий, которые я тестировал, postgres и mysql будут игнорировать все нулевые значения при усреднении, и он вернет NULL, если там здесь нечего усреднять. Это обычно имеет смысл, поскольку NULL следует считать "неизвестным". Если вы хотите переопределить это, вы можете использовать coalesce (как предложил Luc M).
$ create table foo (bar int); CREATE TABLE $ select avg(bar) from foo; avg ----- (1 row) $ select coalesce(avg(bar), 0) from foo; coalesce ---------- 0 (1 row) $ insert into foo values (3); INSERT 0 1 $ insert into foo values (9); INSERT 0 1 $ insert into foo values (NULL); INSERT 0 1 $ select coalesce(avg(bar), 0) from foo; coalesce -------------------- 6.0000000000000000 (1 row)
конечно, "from foo "можно заменить на" from (... тут какая-то сложная логика ...) как Фу"
теперь, должна ли нулевая строка в таблице считаться 0? Затем коалесцируют должен быть использован в СР звонок.
$ select coalesce(avg(coalesce(bar, 0)), 0) from foo; coalesce -------------------- 4.0000000000000000 (1 row)