我正在制定一种汽车统计解决方案,需要每公里行驶收费。
我有下表:
table: cars
columns: car_id, km_driven
table: pricing
columns: from, to, price
我的cars
表中的内容可以是:
car_id, km_driven
2, 430
3, 112
4, 90
pricing
表上的内容可以是:
from, to, price
0, 100, 2
101, 200, 1
201, null, 0.5
意思是,前100公里的价格为每公里2美元,接下来的100公里的价格为每公里1美元,而以上所有里程的价格为每公里0.5美元。
是否有通过cars
为我的PostgreSQL
计算费用的逻辑和简单方法?
因此,如果car
驱动了ex。 201,那么价格将是100x2 + 100x1 + 0.5
,而不是201x0.5
。
答案 0 :(得分:2)
根据@ sean-johnston的答案进行修改:
select
car_id, km_driven,
sum(case
when km_driven>=start then (least(finish,km_driven)-start+1)*price
else 0
end) as dist_price
from cars,pricing
group by car_id,km_driven
摆弄多一点,在适当的位置可以省略大小写
select
car_id, km_driven,
sum((least(finish,km_driven)-start+1)*price) as dist_price
from cars,pricing
where km_driven >= start
group by car_id,km_driven
答案 1 :(得分:2)
我将查询写为:
select c.car_id, c.km_driven,
sum(( least(p.to_km, c.km_driven) - p.from_km + 1) * p.price) as dist_price
from cars c join
pricing p
on c.km_driven >= p.from_km
group by c.car_id, c.km_driven;
这里是db<>fiddle。
答案 2 :(得分:1)
我将肯定使用程序来做到这一点,因为可以使用循环以非常直接的方式实现它。但是,您应该可以执行以下操作:
select car_id, sum(segment_price)
from (
select
car_id,
km_driven,
f,
t,
price,
driven_in_segment,
segment_price
from (
select
car_id,
km_driven,
f,
t,
price,
(coalesce(least(t, km_driven), km_driven) - f) driven_in_segment,
price * (coalesce(least(t, km_driven), km_driven) - f) segment_price
from
-- NOTE: cartesian product here
cars,
pricing
where f < km_driven
)
) data
group by car_id
order by car_id
不过,我发现它的可读性很差。
更新:
该查询比必要的要复杂一些,我正在尝试使用一些窗口函数来完成一些最终不需要的事情。这里的等效简化版本:
select car_id, sum(segment_price)
from (
select
car_id,
km_driven,
f,
t,
price,
(coalesce(least(t, km_driven), km_driven) - f) driven_in_segment,
price * (coalesce(least(t, km_driven), km_driven) - f) segment_price
from
-- NOTE: cartesian product here
cars,
pricing
where f < km_driven
) data
group by car_id
order by car_id
答案 3 :(得分:1)
明智地使用大小写/和组合。但是,首先需要使范围一致。我选择将第一个范围更改为1100。鉴于此,以下内容应会给您希望。 (我还使用了“开始” /“结束”,因为“从/到”是保留字)。
select
car_id, km_driven,
sum (case
when finish is null and km_driven >= start
then (km_driven-start+1) * price
when km_driven >= start
then (case
when (km_driven - start + 1) > finish
then (finish - start + 1)
else (km_driven - start + 1)
end) * price
else 0
end) as dist_price
from cars, pricing
where km_driven >= start
group by 1, 2;
说明:
如果您不想(或无法)使范围保持一致,那么您需要为起始范围添加第三个外壳。
答案 4 :(得分:0)
您可以使用join并通过
时的用例来计算成本 select c.car_id, case when p.price=.5
then 100*2+100*1+(c.km_driven-200)*0.5
when p.price=1 then 100*2+(c.km_driven-100)*1
else c.km_driven*p.price as cost
from cars c join pricing p
on c.km_driven>=p.from and c.km_driven<=p.to