PostgreSQL интересная проблема - PullRequest
0 голосов
/ 18 ноября 2018

Существует 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 - стоимость этих провайдеров.

процентов - процент провайдеров, чтобы избежать жертв.

Мне нужно написать запрос, который обнаружит 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

Iне знаю, правильно ли этот частичный запрос и что делать дальше.

Ответы [ 2 ]

0 голосов
/ 18 ноября 2018

Если я правильно понял вопрос, вы ищете все пары провайдеров из таблицы мер, чья общая стоимость меньше 100000, а суммарный процент - максимум

Проверьте, помогает ли следующее. Один из способов сделатьэто будет выглядеть следующим образом:

  1. Декартово произведение таблиц и отфильтровывание условия самостоятельного объединения
  2. Суммирование столбца процента и суммирование столбца mcost
  3. Фильтрацияmcost summed_up должен быть <100000 </li>
  4. , упорядочен по процентному значению summed_up и получит первое значение.

Я создал тестовый пример следующим образом

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

Обновлено DEMO https://dbfiddle.uk/?rdbms=postgres_8.4&fiddle=7db3297721500ee926c590207a1e57e7

0 голосов
/ 18 ноября 2018

Рассмотрите возможность расчета двух 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...