[英]PostgreSQL and matching row on multiple
我正在制定一種汽車統計解決方案,需要每行駛一公里就收費一次。
我有下表:
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美元。
是否存在通過PostgreSQL
計算我的cars
成本的邏輯和簡單方法?
因此,如果car
已經行駛。 201,那么價格將是100x2 + 100x1 + 0.5
,而不是201x0.5
。
修改自@ 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
我將查詢寫為:
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 。
我一定會使用一個過程來完成此操作,因為可以使用循環以非常簡單的方式來實現它。 但是,您應該能夠執行以下操作:
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
明智地使用大小寫/總和組合。 但是,首先需要使范圍一致。 我選擇將第一個范圍更改為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;
說明:
如果您不想(或無法)使范圍保持一致,則需要為起始范圍添加第三個外殼。
您可以使用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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.