Как привести последние 5 регистров каждого идентификатора с SQL? - PullRequest
0 голосов
/ 14 октября 2019

У меня есть таблица с регистрами покупок. Есть все реестры покупок зоомагазина, начиная с 2010 года. Мне нужна помощь, чтобы принести только последние пять покупок каждого клиента.

Я пытался, но это не работает. Это приносит мне последние 5 регистров всей таблицы, а не каждого клиента.

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

Мне нужен такой вид возврата:

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

Ответы [ 2 ]

3 голосов
/ 14 октября 2019

Использование 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
1 голос
/ 14 октября 2019

Вы можете использовать CROSS APPLY следующим образом:

DECLARE @Registry TABLE (client_name VARCHAR(100), purchase_date DATETIME,  item INT)
INSERT INTO @Registry
(client_name, purchase_date, item)
VALUES
('Client1', '1/1/2019', 1), 
('Client1', '2/1/2019', 2),
('Client1', '3/1/2019', 3),
('Client1', '4/1/2019', 4),
('Client1', '5/1/2019', 5),
('Client1', '6/1/2019', 6),
('Client1', '7/1/2019', 7),
('Client2', '1/1/2019', 1), 
('Client2', '2/1/2019', 2),
('Client2', '3/1/2019', 3),
('Client2', '4/1/2019', 4),
('Client2', '5/1/2019', 5),
('Client2', '6/1/2019', 6),
('Client2', '7/1/2019', 7)

;WITH Clients AS (
    SELECT client_name FROM @Registry GROUP BY client_name
)
SELECT C.*, P.purchase_date, P.item
    FROM Clients AS C
    CROSS APPLY 
    (
        SELECT TOP 5 R.purchase_date, R.item 
        FROM @Registry R 
        WHERE R.client_name = C.client_name
        ORDER BY R.purchase_date DESC
    ) P
ORDER BY C.client_name, P.purchase_date, P.item

Вот результат:

client_name purchase_date   item
Client1 2019-03-01 00:00:00.000 3
Client1 2019-04-01 00:00:00.000 4
Client1 2019-05-01 00:00:00.000 5
Client1 2019-06-01 00:00:00.000 6
Client1 2019-07-01 00:00:00.000 7
Client2 2019-03-01 00:00:00.000 3
Client2 2019-04-01 00:00:00.000 4
Client2 2019-05-01 00:00:00.000 5
Client2 2019-06-01 00:00:00.000 6
Client2 2019-07-01 00:00:00.000 7
...