найти максимум в столбце, но только при совпадении двух других столбцов - PullRequest
0 голосов
/ 27 октября 2018

Мне нужна помощь в PostgreSQL. У меня есть две таблицы

  1. Predicton - предсказывает будущие бедствия и жертвы для каждого города.
  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 голосов
/ 27 октября 2018

Сначала создайте все пары провайдеров и выполните расчет потерь и затрат:

  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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...