PostgreSQL有趣的问题

时间:2018-11-18 01:31:16

标签: sql postgresql

有5种关系:

Event (etype, description)                      primary key - etype

City (cname, country, population)               primary key - cname

Disaster (cname, dyear, etype, casualties)      primary keys - cname, dyear

Prediction (cname, etype, casualties)           primary keys - cname, etype

Measures (etype, provider, mcost, percent)      primary keys - etype, provider

etype-灾难类型。

提供者-警察,消防部门...

mcost-这些提供者的费用。

percent-避免人员伤亡的提供者的百分比。

我需要写一个查询,找出两个成功的提供者来预测城市中的灾难。两者的费用不得超过1,000,000。

2个成功的提供者定义为可能的最大总和。

到目前为止,我已经拥有了:

select
from prediction, measures as m1, measures as m2
where m1.provider < m2.provider AND (m1.mcost + m2.mcost <= 1000000) 
AND m1.percent + m2.percent >= all (select

我不知道此部分查询是否正确以及下一步该怎么做。

2 个答案:

答案 0 :(得分:1)

请考虑计算两个CTE:所有不同的提供者对以及每个对的最大百分比。然后在主查询中加入两个CTE:

WITH provider_pairs AS (
       SELECT m1.provider AS provider1, m2.provider AS provider2, 
              m1.percent + m2.percent AS sum_percent
       FROM measures m1
       INNER JOIN  measures m2 ON m1.provider < m2.provider
       INNER JOIN prediction p ON p.etype = m1.etype AND p.etype = m2.etype
       WHERE (m1.mcost + m2.mcost <= 1000000) 
  ),
   max_pct AS (
       SELECT MAX(sum_percent) AS max_percent
       FROM provider_pairs p
  )

SELECT p.provider1, p.provider2
FROM provider_pairs p
INNER JOIN max_pct m ON p.sum_percent = m.max_percent

答案 1 :(得分:0)

如果我的问题正确,那么您正在从度量表中查找所有对提供者,这些提供者的总mcost小于100000,且其总百分比最大。

查看以下内容是否有帮助 一种方法如下:

  1. 笛卡尔乘积表并筛选出自联接条件
  2. 总结百分比列,总结mcost列
  3. 过滤出summed_up mcost为<100000
  4. 按summed_up百分比desc排序,并获得第一个值。

我创建了一个测试用例,如下所示

create table measures(provider varchar(50),mcost int, percent int);

insert into measures values('Police',30000,80);
insert into measures values('Fire Department',50000,40);
insert into measures values('Military',40000,50);
insert into measures values('Medical',45000,70);

select * from (
         select row_number() over(order by x.max_percent desc) as rnk
               ,x.*
           from (
         select a.provider
                ,b.provider
                ,greatest(a.provider,b.provider) as combo_pair
                ,a.percent+b.percent as summed_percent
                ,a.mcost+b.mcost as summed_mcost
                ,max(a.percent+b.percent) over(partition by greatest(a.provider,b.provider)) as max_percent
           from measures a
           join measures b
             on 1=1
         where a.provider <> b.provider    
           and a.mcost+b.mcost <100000 /*Check for the combined cost to be <100000*/
         )x
         where x.max_percent=x.summed_percent
)y
where y.rnk=1

更新后的演示 https://dbfiddle.uk/?rdbms=postgres_8.4&fiddle=7db3297721500ee926c590207a1e57e7