【问题标题】:PostgreSQL interesting issuePostgreSQL 有趣的问题
【发布时间】:2018-11-18 01:31:15
【问题描述】:

有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 - 避免人员伤亡的供应商百分比。

我需要编写一个查询,找出 2 个成功的提供者来预测城市中的灾难。两者的成本不得高于 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

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

【问题讨论】:

  • “不知道这个部分查询对不对”---那么运行看看?
  • 运行部分查询?为什么?
  • 请学习使用显式 ANSI 标准连接语法,例如“内连接” “左外连接”。拒绝在 from 子句中在表名之间放置逗号的选项。
  • 为什么有人会运行部分查询? 查看该位是否有效。 如果没有,请修复它。如果是,请继续下一位。
  • 我没有扔****。您问为什么有人会运行部分查询。如果你不愿意接受建议,那很好,但没有必要到处侮辱。运行部分代码是一种有效的 SQL 方法。

标签: sql postgresql


【解决方案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

【讨论】:

  • max_pct...的部分(第9-11行)连接到WITH子句?
  • 而且我也无法理解它将如何选择具有最大百分比的对
  • WITH 定义可以是一个或多个逗号分隔列表的 CTE。最后一个SELECT 语句的JOIN 子句在加入两个CTE 时选择具有最大百分比的对(可能超过一对)。
【解决方案2】:

如果我的问题是正确的,那么您正在从度量表中寻找所有组合 mcost 小于 100000 且组合百分比为最大值的提供者对

看看以下是否有帮助 一种方法如下

  1. 笛卡尔积表并过滤掉自联接条件
  2. 总结百分比列和总结 mcost 列
  3. 过滤掉 summed_up mcost 为
  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

【讨论】:

  • 我忘了说我在这里既不能使用order by也不能使用limit :)
猜你喜欢
  • 1970-01-01
  • 2011-09-27
  • 2013-01-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多