我需要PostgreSQL中的帮助。 我有两个桌子
每种灾难和提供者的合并都有一定程度的避免人员伤亡(度量值的百分比*该灾难的预计伤亡人数* 0.01)。
对于城市和灾难的每种组合,我需要找到两个提供商 1)它们的总成本不到一百万 2)避免的伤亡人数最多。
到目前为止我的工作和产品
select o1.cname, o1.etype, o1.provider as provider1, o2.provider as provider2, (o1.averted + o2.averted) averted_casualties
from (select cname, m.etype, provider, mcost, (percent*Casualties*0.01)averted
from measures m, prediction p
where (m.etype = p.etype)) as o1, (select cname, m.etype, provider, mcost, (percent*Casualties*0.01)averted
from measures m, prediction p
where (m.etype = p.etype)) as o2
where (o1.cname = o2.cname) and (o1.etype = o2.etype) and (o1.provider < o2.provider) and (o1.mcost + o2.mcost < 1000000)
如何更改此查询,以便它将为我显示每个城市/灾难组合的最佳averted_casualties(不仅是所有表格的最大值,每个组合的最大值) 这是理想的结果:
P.S。我不允许使用排序,视图或功能。
答案 0 :(得分:0)
首先,构造所有供应商对,并进行人员伤亡和费用计算:
select p.*, m1.provider as provider_1, m2.provider as provider_2,
p.casualties * (1 - m1.percent / 100.0) * (1 - m2.percent / 100.0) as net_casualties,
(m1.mcost + m2.mcost) as total_cost
from measures m1 join
measures m2
on m1.etype = m2.etype and m1.provide < m2.provider join
prediction p
on m1.etype = p.etype;
然后,应用您的条件。通常,您将使用窗口函数,但是由于本练习不允许排序,因此您想使用子查询:
with pairs as (
select p.*, m1.provider as provider_1, m2.provider as provider_2,
p.casualties * (1 - m1.percent / 100.0) * (1 - m2.percent / 100.0) as net_casualties,
(m1.mcost + m2.mcost) as total_cost
from measures m1 join
measures m2
on m1.etype = m2.etype and m1.provide < m2.provider join
prediction p
on m1.etype = p.etype;
)
select p.*
from pairs p
where p.total_cost < 1000000 and
p.net_casualties = (select min(p2.net_casualties)
from pairs p2
where p2.city = p.city and p2.etype = p.etype and
p2.total_cost < 1000000
);
避免的伤亡人数最多,导致的净伤亡人数最少。他们是同一回事。
关于您尝试的解决方案。仅仅看到,
子句中的from
告诉我,您需要研究join
。简单规则:从不在from
子句中使用逗号。始终使用正确,明确,标准 join
的语法。
您重复的子查询还表明您需要了解CTE。