平均 Postgres 中的多列
Average Multiple Columns in Postgres
我有一个包含多行的 table,每行包含以下四列:
product
price_instore
price_pickup
price_delivery
price_ship
1
.00
.50
.50
.00.
2
.00
.00
NULL
NULL
3
.00
.00
.00
NULL
我想要第五列 average_price 给出产品的平均价格,但不将 NULLS 计入总价或用于除以平均值的计数。
因此产品 1 的平均价格:($13+$13.50+$14.50+$18)/4=$14.75
产品 2 的平均价格:($4+$4)/2 = $4.00
产品 3 的平均价格:($10+$10+$12)/3 = $10.67
SQL有什么办法吗?我试过如下子查询但没有成功:
(select coalesce((PRICE_INSTORE + PRICE_PICKUP + PRICE_DELIVERY + PRICE_SHIP) / 4,
PRICE_INSTORE, PRICE_PICKUP, PRICE_DELIVERY, PRICE_SHIP)
但如果其中任何一个为空,我只能得到一个价格
我喝醉了,所以可能有比旋转更好的方法来做到这一点,但我现在看不到它,因为房间像它一样在我周围旋转。
with j as (
select product, to_jsonb(mytable) - 'product' as jdata
from mytable
)
select j.product, avg(e.value::numeric) as avg_price
from j
cross join lateral jsonb_each(j.jdata) as e(key, value)
where e.value is not null
group by j.product.
一种方法是横向连接:
select t.*, avg_price
from t cross join lateral
(select avg(price) as avg_price
from (values (price_instore), (price_pickup), (price_delivery), (price_ship)
) v(price)
) x
select
*,
(select avg(x) from unnest(array[price_instore,price_pickup,price_delivery,price_ship]) as x) as avg_price
from
your_table;
试试这个:
select coalesce(PRICE_INSTORE,0) + coalesce(PRICE_PICKUP,0) + coalesce(PRICE_DELIVERY,0) + coalesce(PRICE_SHIP,0)) / 4
这一个可能是最容易消化的。性能应该不会太差,除非你有一个非常大的 table 也没有索引
with cte (product, prices) as
(select product, price_instore from t union all
select product, price_pickup from t union all
select product, price_delivery from t union all
select product, price_ship from t)
select product, avg(prices)
from cte
group by product;
您要么按原样使用输出,要么将其包装在另一个 CTE 上并使用它加入您的原始 table 以获得平均值
试试这个
select coalesce (PRICE_INSTORE, 0 ) + coalesce (PRICE_PICKUP, 0) + coalesce (PRICE_DELIVERY , 0) + coalesce (PRICE_SHIP , 0) /
((case when PRICE_INSTORE is null then 0 else 1 end) + (case when PRICE_PICKUP is null then 0 else 1 end) +
(case when PRICE_DELIVERY is null then 0 else 1 end) + (case when PRICE_SHIP is null then 0 else 1 end) )
from product
我有一个包含多行的 table,每行包含以下四列:
product | price_instore | price_pickup | price_delivery | price_ship |
---|---|---|---|---|
1 | .00 | .50 | .50 | .00. |
2 | .00 | .00 | NULL | NULL |
3 | .00 | .00 | .00 | NULL |
我想要第五列 average_price 给出产品的平均价格,但不将 NULLS 计入总价或用于除以平均值的计数。
因此产品 1 的平均价格:($13+$13.50+$14.50+$18)/4=$14.75
产品 2 的平均价格:($4+$4)/2 = $4.00
产品 3 的平均价格:($10+$10+$12)/3 = $10.67
SQL有什么办法吗?我试过如下子查询但没有成功:
(select coalesce((PRICE_INSTORE + PRICE_PICKUP + PRICE_DELIVERY + PRICE_SHIP) / 4,
PRICE_INSTORE, PRICE_PICKUP, PRICE_DELIVERY, PRICE_SHIP)
但如果其中任何一个为空,我只能得到一个价格
我喝醉了,所以可能有比旋转更好的方法来做到这一点,但我现在看不到它,因为房间像它一样在我周围旋转。
with j as (
select product, to_jsonb(mytable) - 'product' as jdata
from mytable
)
select j.product, avg(e.value::numeric) as avg_price
from j
cross join lateral jsonb_each(j.jdata) as e(key, value)
where e.value is not null
group by j.product.
一种方法是横向连接:
select t.*, avg_price
from t cross join lateral
(select avg(price) as avg_price
from (values (price_instore), (price_pickup), (price_delivery), (price_ship)
) v(price)
) x
select
*,
(select avg(x) from unnest(array[price_instore,price_pickup,price_delivery,price_ship]) as x) as avg_price
from
your_table;
试试这个:
select coalesce(PRICE_INSTORE,0) + coalesce(PRICE_PICKUP,0) + coalesce(PRICE_DELIVERY,0) + coalesce(PRICE_SHIP,0)) / 4
这一个可能是最容易消化的。性能应该不会太差,除非你有一个非常大的 table 也没有索引
with cte (product, prices) as
(select product, price_instore from t union all
select product, price_pickup from t union all
select product, price_delivery from t union all
select product, price_ship from t)
select product, avg(prices)
from cte
group by product;
您要么按原样使用输出,要么将其包装在另一个 CTE 上并使用它加入您的原始 table 以获得平均值
试试这个
select coalesce (PRICE_INSTORE, 0 ) + coalesce (PRICE_PICKUP, 0) + coalesce (PRICE_DELIVERY , 0) + coalesce (PRICE_SHIP , 0) /
((case when PRICE_INSTORE is null then 0 else 1 end) + (case when PRICE_PICKUP is null then 0 else 1 end) +
(case when PRICE_DELIVERY is null then 0 else 1 end) + (case when PRICE_SHIP is null then 0 else 1 end) )
from product