[英]SQL query to calculate expenses based on several tables
我正在执行一项大型(不是真实的)任务来管理多个国家/地区的开支。 我已经计算了每个城镇的投资能力,现在我需要计算建造这些飞船的预算。 任务如下:
我们有下面的表格(有表格 Town 和 Spaceship,但这里没有它们任务很清楚)。 我们需要计算完成每一种可供生产的舰船需要多少钱。 因此,我们有不同类型的宇宙飞船,每种类型需要不同类型的零件(参见表 Spaceship_required_part)。 每个城镇都生产几种类型的零件(见表 Spaceship_part_in_town)。 我们需要计算成本是多少(参见 Spaceship_part 中的成本,Spaceship_part_in_town 中的阶段,以及 Spaceship_required_part 中的金额),以构建每个可用类型的宇宙飞船单元。 我们所说的可用是指可以在给定城市中找到所需的零件。 我们计算给定城市的预算(我可以自己为其中的 rest 个城市计算预算)。
create table Spaceship_part(
id int PRIMARY KEY,
name text,
cost int
);
create table Spaceship_part_in_town(
id int PRIMARY KEY,
spaceship_part_id int references Spaceship_part,
city_id int references Town,
stage float -- the percentage of completion of the part
);
create table Spaceship_required_part(
id int PRIMARY KEY,
spaceship_part int references Spaceship_part,
spaceship int references Spaceship,
amount int -- amount of a particular part needed for the given spaceship
);
我知道如何使用编程语言解决此任务,但我的 SQL 技能不是那么好。 我知道首先我需要检查我们可以使用镇上可用的部件建造哪些宇宙飞船。 这可以使用所需零件 ( amount
) 和城镇可用零件 ( count(spaceship_part_id)
) 的计数器来完成。 然后我需要使用公式(100-stage)*cost/100
计算建造每艘宇宙飞船所需的总和。
但是,我不知道如何在 SQL 代码中编写它。 我正在写 PostgreSQL。
数据 model 是这样的:
要以最少的建造成本建造宇宙飞船,我们可以:
Step 1. 计算一个part的build_cost
= (100 - stage) * cost / 100; 对于每个部分,根据阶段对建造成本进行排序,以便我们将宇宙飞船的总成本降至最低。
Step 2. 基于build_cost
,我们根据需要的数量计算出一个零件的total_cost
(以便与spaceship_required_part.amount
rt.amount 进行比较),并在part_sources
中记录零件的来源,格式为 CSV (city_id, stage, build_cost),...
第 3 步。一旦我们有了可用零件和总数量和成本计算,我们将它与 spaceship_required_part 结合起来得到这样的结果:
spaceship_id|spaceship_part_id|amount|total_cost|part_sources |
------------+-----------------+------+----------+---------------------+
1| 1| 2| 50.0|(4,80,20),(3,70,30) |
1| 2| 1| 120.0|(1,40,120) |
2| 2| 2| 260.0|(1,40,120),(2,30,140)|
2| 3| 1| 180.0|(2,40,180) |
3| 3| 2| 360.0|(2,40,180),(4,40,180)|
上面告诉我们要构建:
第一次迭代后,我们可以更新spaceship_part_in_town
并从spaceship_required_part
rt 中删除第一艘宇宙飞船,然后再次运行查询以获取要建造的第二艘宇宙飞船及其部件来源。
with cte_part_sources as (
select spt.spaceship_part_id,
spt.city_id,
sp.cost,
spt.stage,
(100.0-spt.stage)*sp.cost/100.0 as build_cost,
row_number() over (partition by spt.spaceship_part_id order by spt.stage desc) as cost_rank
from spaceship_part_in_town spt
join spaceship_part sp
on spt.spaceship_part_id = sp.id),
cte_parts as (
select spaceship_part_id,
city_id,
cost_rank,
cost,
stage,
build_cost,
cost_rank as total_qty,
sum(build_cost) over (partition by spaceship_part_id order by cost_rank) as total_cost,
string_agg('(' || city_id || ',' || stage || ',' || build_cost || ')',',') over (partition by spaceship_part_id order by cost_rank) as part_sources
from cte_part_sources)
select srp.spaceship_id,
srp.spaceship_part_id,
srp.amount,
p.total_cost,
p.part_sources
from spaceship_required_part srp
left
join cte_parts p
on srp.spaceship_part_id = p.spaceship_part_id
and srp.amount = p.total_qty;
编辑:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.