Search code examples
sql-servert-sqldategreatest-n-per-groupwindow-functions

How to bring the last 5 register of each ID with SQL?


I have a table with the purchase registers. There are all the purchase registers of a Pet Shop, since 2010. I need some help to bring only the last five purchase of each client.

I was trying, but it is not working. It brings me the last 5 registers of all the table, and not of each client.

SELECT TOP (5) [client_name],
        [purchase_date],
        [item]
FROM [Pet_Shop]
ORDER BY client_name 
WHERE client_name in ('John', 'Mary', 'Austin')

I need this kind of return:

client_name | purchase_date | item 
___________________________________
John        | 2019-09-14    | food
John        | 2019-09-13    | ball
John        | 2019-09-12    | shampoo
John        | 2019-09-11    | cookie
John        | 2019-09-11    | food
Mary        | 2019-09-14    | collar
Mary        | 2019-07-14    | food
Mary        | 2019-06-14    | toy
Mary        | 2019-06-14    | hamster
Mary        | 2019-05-14    | food
Austin      | 2019-09-18    | food
Austin      | 2019-09-11    | collar
Austin      | 2019-09-10    | toy
Austin      | 2019-09-09    | catnip
Austin      | 2019-09-11    | food

Solution

  • Use ROW_NUMBER():

    SELECT *
    FROM (
        SELECT 
            client_name,
            purchase_date,
            item,
            ROW_NUMBER() OVER(PARTITION BY client_name ORDER BY purchase_date desc) rn
        FROM Pet_Shop
        WHERE client_name in ('John', 'Mary', 'Austin')
    ) x
    WHERE rn <= 5
    ORDER BY client_name