Группируйте min (значение) по неосновному ключевому атрибуту и ​​присоединяйте дополнительный атрибут из той же строки (с необработанным SQL или SQLalchemy) - PullRequest
0 голосов
/ 13 мая 2018

Учитывая, что у меня есть следующая таблица "PriceRecord":

| PriceRecord_ID | Company_ID | Price | Tarif_type | Tarif_Model | ... attributes |
|:--------------:|:----------:|:-----:|:----------:|:----------:|:--------------:|
|        1       |      A     |   10  |   tarif_1  |   Model_1   |       ...      |
|        2       |      A     |   20  |   tarif_2  |   Model_1   |       ...      |
|        3       |      A     |   10  |   tarif_3  |   Model_2   |       ...      |
|        4       |      B     |   11  |   tarif_1  |   Model_2   |       ...      |
|        5       |      B     |   15  |   tarif_2  |   Model_3   |       ...      |
|        6       |      C     |   10  |   tarif_1  |   Model_4   |       ...      |

Моя цель - получить минимальную цену для каждой компании. Для каждой минуты (Цена) мне также нужны другие атрибуты (например, Tarif_type, Tarif_name).

Ожидаемый результат:

| PriceRecord_ID | Company_ID | Price | Tarif_type | Tarif_Model | ... attributes |
|:--------------:|:----------:|:-----:|:----------:|:----------:|:--------------:|
|        1       |      A     |   10  |   tarif_1  |   Model_1   |       ...      |
|        4       |      B     |   11  |   tarif_1  |   Model_1   |       ...      |
|        6       |      C     |   10  |   tarif_1  |   Model_2   |       

Я знаю, как получить мин (цена) и группировать по компании. Моя проблема в том, что я не могу присоединиться к другим атрибутам (поскольку название компании не является уникальным ключом.

Я пробовал этот запрос (с намерением присоединиться к таблице, ЕСЛИ оба условия соблюдены -> к сожалению, он объединяется два раза для каждого условия, и у меня есть более одной записи для каждой компании в моей таблице результатов)

    subquery = db.session.query(PriceRecord.company_id, db.func.min(PriceRecord.Price).label("minPrice")) \
        .group_by(PriceRecord.company_id) \
        .subquery()
    result = db.session.query(subquery.c.company_id, subquery.c.minPrice, PriceRecord.tarif_type, PriceRecord.tarif_model) \
    .join(PriceRecord, subquery.c.insurance_company==PriceRecord.company_id and subquery.c.minPrice==PriceRecord.Price) \

Я нашел это подобное решение, но не смог реализовать его для моего сценария.

Любая помощь высоко ценится! заранее спасибо

Ответы [ 2 ]

0 голосов
/ 14 мая 2018

После некоторых исследований я смог получить ожидаемый результат с помощью следующего кода sql:

select * 
from
 (
  select
    row_number () over (partition by company_ID order by premium asc) as rownumber, 
    min(Price) over (partition by company_ID) as minimalPrice, *
  FROM price_table
 ) subquery
where subquery.rownumber = 1

С помощью так называемых оконных функций вы можете использовать агрегатные функции без оператора group_by.Функция rownumber присваивает каждой записи цены созданный номер «на лету» (из-за функции разбиения rownumber снова начинается с 1 для каждой компании).Поскольку мне нужен точный один результат для каждой компании, я фильтрую по rownumber = 1.

Вот пример моего внутреннего выбора (без фильтрации, где rownumber = 1)

rownumber minprice company_id  price
   1       408.9      8         408.9
   2       408.9      8         436.1
   3       408.9      8         439.7
   4       408.9      8         463.1
   5       408.9      8         468.9
   6       408.9      8         490.3
   7       408.9      8         498
   8       408.9      8         517.5
   9       408.9      8         527.2
   10      408.9      8         528.2
   11      408.9      8         556.4
   12      408.9      8         568
   1       364.4      32        364.4
   2       364.4      32        387.6
   3       364.4      32        391.8
   4       364.4      32        416.8
   5       364.4      32        419.3
   6       364.4      32        446
   7       364.4      32        446.6
   8       364.4      32        474.1
   9       364.4      32        475.1
   10      364.4      32        485
   11      364.4      32        504.3
   12      364.4      32        515.9
   1       412        57        412
   2       412        57        433.7
   3       412        57        439.7

Я надеюсь, что этопомогает, мне потребовалось некоторое время, чтобы покопаться в этих функциях sql.

0 голосов
/ 13 мая 2018
SELECT b.*
FROM (
  SELECT Company, MIN(Price) Price FROM PriceRecord GROUP BY Company
  ) a
JOIN PriceRecord b on a.Company = b.Company and a.Price = b.Price

Одна оговорка - если компания А имеет две строки с ценой 10, оба вернутся.

...