Как обновить ячейки таблицы из столбцов другой таблицы с другими условиями? - PullRequest
0 голосов
/ 11 апреля 2020

Предположим, у меня есть две таблицы в моей базе данных, как показано ниже:

Таблица 1 (current_prices): которая содержит некоторые товары и их цены и обновляется один раз в день:

# current_prices
| commodity  | price |
____________________
|  stuff1    | price1
|  stuff2    | price2
|  stuff3    | price3
|.           |
|.           |
|.           |
|  stuffN    | priceN

Таблица 2 (stat_history): которые делят продукты в ценовых диапазонах и сохраняют количество элементов каждого диапазона для всех дней, как показано ниже:

# stat_history
|   date    | range1_count | range2_count | range3_count
________________________________________________________
|  20200411 |       12     |      5       |      9
|  20200412 |       10     |      5       |      11
|  20200413 |       13     |      4       |      9
|  20200414 |       15     |      3       |      8

Содержимое таблицы stat_history создается из current_price содержимое в конце дня.

В настоящее время я использую несколько Update-Insert (Upsert) запросов для обновления моей таблицы stat_history, как показано ниже:

insert into stat_history (date, range1_count)
    select now()::date , count(stuff) as range1_count from current_prices
        where 0 < price and price < VAL1
    on conflict(day)
        update set
            range1_count = excluded.range1_count

insert into stat_history (date, range2_count)
    select now()::date , count(stuff) as range2_count from current_prices
        where VAL1 < price and price < VAL2
    on conflict(day)
        update set
            range2_count = excluded.range2_count

..... (blah blah)

вопрос:

Есть ли какой-нибудь более короткий, простой или более эффективный способ сделать это (например, в одном запросе SQL)?

1 Ответ

1 голос
/ 11 апреля 2020

Вы можете делать условные подсчеты, используя Postgres стандарт filter предложение:

insert into stat_history (date, range1_count)
select 
    now()::date, 
    count(stuff) filter(where price >= 0 and price < VAL1) as range1_count,
    count(stuff) filter(where price >= VAL1 and price < VAL2) as range2_count
from current_prices
where price >= 0 and price < VAL2
on conflict(day) 
update set 
    range1_count = excluded.range1_count
    range2_count = excluded.range2_count

Примечания:

  • Я адаптировал логику c, что помещает строки в интервалы, чтобы сделать их смежными (например, в исходном запросе цена, равная VA1, никогда не будет учитываться)

  • с этими логами c под рукой вам может даже не понадобиться on conflict предложение

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