I'm tracking game prices across multiple stores. I have a games
table:
id | title | platform_id
---|-------------|-----------
1 | Super Mario | 1
2 | Tetris | 3
3 | Sonic | 2
a stores
table:
id | title
---|-------------
1 | Target
2 | Amazon
3 | EB Games
and a copies
table with one entry for Target's copy of a given game, one entry for Amazon's, etc. I store the SKU so I can use it when scraping their websites.
game_id | store_id | sku
--------|----------|----------
1 | 2 | AMZ-3F4YK
1 | 3 | 001481
I run one scrape a day or a week or however long, and I store the result as cents in a prices
table:
sku | price | time
----------|---------|------
AMZ-3F4YK | 4010 | 13811101
001481 | 3210 | 13811105
Plus a platforms table that just maps IDs to names.
Here's where I get confused and stuck.
I want to issue a query that selects each game, plus its most recent price at each store. So it would net results like
games.title | platform_name | info
------------|---------------|------
Super Mario | NES | EB Games,1050;Amazon,3720;Target,5995
Tetris | Game Boy | EB Games,3720;Amazon,410;Target,5995
My best attempt thus far is
select
games.title as title,
platforms.name as platform,
group_concat(distinct(stores.name) || "~" || prices.price) as price_info
from games
join platforms on games.platform_id = platforms.id
join copies on copies.game_id = games.id
join prices on prices.sku = copies.sku
join stores on stores.id = copies.store_id
group by title
Which nets results like
Super Mario | NES | EB Games~2300,Target~2300,Target~3800
that is, it includes every price listed, when I only want one per store (and for it to be the most recent). Figuring out how to integrate the 'select price where id = (select id from max(time)...' etc subquery to sort this out has totally stumped me all night and I'd appreciate any advice anyone could offer me.
I'm using SQLite, but if there's a better option in Postgres I could do it there.
答案 0 :(得分:1)
您需要两个层次的聚合。 。 。而且,Postgres对此要简单得多,因此我将使用Postgres语法:
select title, platform,
string_agg(s.name || '~' pr.price order by s.name)
from (select distinct on (g.title, p.name, s.name) g.title as title, p.name as platform, s.name, pr.price
from games g join
platforms p
on g.platform_id = p.id join
copies c
on c.game_id = g.id join
prices pr
on pr.sku = c.sku join
stores s
on s.id = c.store_id
group by g.title, p.name, s.name, pr.time desc
) gps
group by title, platform