找到一列中的最大值,但仅在其他两列匹配时

时间:2018-10-27 16:43:38

标签: sql postgresql

我需要PostgreSQL中的帮助。 我有两个桌子

  1. 预测-预测每个城市的未来灾难和人员伤亡。
  2. 措施适合每种灾害的损害控制提供者的类型(包括成本和“平均伤亡人数”百分比)

tables

每种灾难和提供者的合并都有一定程度的避免人员伤亡(度量值的百分比*该灾难的预计伤亡人数* 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)

outcome of current work

如何更改此查询,以便它将为我显示每个城市/灾难组合的最佳averted_casualties(不仅是所有表格的最大值,每个组合的最大值) 这是理想的结果:

desired

P.S。我不允许使用排序,视图或功能。

1 个答案:

答案 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。