Reputation: 6116
Let assume that I have two tables in my database as below:
Table 1 (current_prices): Which contains some stuffs and their prices and it updates one time per day:
# current_prices
| commodity | price |
____________________
| stuff1 | price1
| stuff2 | price2
| stuff3 | price3
|. |
|. |
|. |
| stuffN | priceN
Table 2 (stat_history): Which divide stuffs in price ranges and keep the number of elements of each range for all days as below:
# 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
The content of stat_history
table are generated from current_price
contents at the end of the day.
Currently I use multiple Update-Insert (Upsert) queries to update my stat_history table as below:
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)
The question is:
Is there any shorter, simpler or more efficient way to do this (In a single SQL query for example)?
Upvotes: 0
Views: 24
Reputation: 222462
You could do conditional counts, using Postgres standard filter
clause:
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
Notes:
I adapted the logic that puts rows in the intervals to make them contiguous (in your original query for example, a price that is equal to VA1
would never be counted in)
with this logic at hand, you might not even need the on conflict
clause
Upvotes: 1