简体   繁体   中英

postgresql - join tables with limit

I want to show a user of his purchase summary from each store, up to first 3 purchases from each store. For simplicity sake, the number of purchases is not configurable. So, it is not the first N, but the first 3

Let say I have these tables with these columns

Store
    id
    name

Product
    id
    name
    storeId
    price

Purchase
    id
    userId
    productId
    count
    purchaseTime

This is what I want to display

-----------------------------------------------
| store     | product         | count | price |
-----------------------------------------------
| disney    | stitch doll     | 1     | 30  |
|           | donald cap      | 3     | 15  |
|           | ticket          | 2     | 100 |
-----------------------------------------------
| universal | iron man figure | 1     | 100 |
|           | batman figure   | 1     | 90  |
-----------------------------------------------

Preferably, if the user purchases donald caps on 2 separate purchases (assumed that price will never change), the number of purchases will be combined

for example: if the user purchases 2 donald caps and then purchase 1 cap, the result will be 3 donald caps - instead of 2 donald caps & 1 donald cap

I am using hibernate and postgresql

I don't even know where to start, in particular how to limit each store purchases to 3 for each store

Any hint, psudo solution or solutions will be appreciated

thanks

Note: Unfortunately, there is a major oversight on my part. I think I want to get each summary in 1 line

For example

id | Store     | Product1        | count1 | price1 | Product2      | count2 | price2 | Product3 | count3 | price3
----------------------------------------------------------------------------------------------------------------------------------
2  | Disney    | stitch doll     | 1      | 30     | donald cap    | 3      | 15     | ticket    | 2     | 100
5  | Universal | iron man figure | 1      | 100    | batman figure | 1      | 90     | null      | null  | null

The reason is: I need to paginate the result - displaying 10 purchase summaries per page If each summary returns 1-3 rows, it is hard to figure out the result of the next page

You could use a lateral join to retrieve the first 3 purchases of each store:

select s.name, p.*
from store s
cross join lateral (
    select pr.name as product, pu.count, pr.price
    from purchase pu
    inner join product pr on pr.id = pu.productid
    where pr.storeid = s.id and pu.userid = ?
    order by pu.purchasetime
    limit 3
) p

Alternatively, you can use row_number() :

select *
from (
    select pr.name as product, pu.count, pr.price,
        row_number() over(partition by s.id order by pu.purchasetime) rn
    from purchase pu
    inner join product pr on pr.id = pu.productid
    inner join store s on s.id = pr.storeid 
    where pu.userid = ?
) t
where rn <= 3

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM