Acho que preciso obter as N coisas mais recentes acessadas por cada usuário e tenho uma tabela de log de todos os acessos. Algo como
CREATE TABLE [AccessLog] ([UserId] UNIQUEIDENTIFIER, [ThingId] UNIQUEIDENTIFIER, [AccessDate] DATETIME)
Então eu escrevi
SELECT [UserId], [ThingId], [SequenceNumber]
FROM (SELECT [UserId], [ThingId], DENSE_RANK()
OVER (PARTITION BY [UserId] ORDER BY [AccessDate] DESC) SequenceNumber
FROM [AccessLog]
) [AccessLog]
WHERE [SequenceNumber] < @N
Isso não funciona porque, se o mesmo usuário acessou a mesma coisa repetidamente, obtemos o mesmo [ThingId]
de volta até N vezes, em vez de N [ThingIds]
de volta distintas para cada usuário.
Estou perplexo como realmente fazê-lo. A tabela é tão grande que, se eu tiver que escrever a junção N ao cubo como se fosse 2.000 novamente (juntar a tabela novamente uma vez para excluir cópias duplicadas e uma segunda vez para gerar a contagem), será mais rápido sugar toda a tabela e processá-lo no código do aplicativo.
É quase como eu quero
FOR EACH [UserId] IN (SELECT [UserId] IN [User])
SELECT TOP (@N) [UserId], [ThingId]
FROM [AccessLog]
ORDER BY [AccessDate] DESC
Mas esse desempenho também é tão ruim que eu gostaria de ler melhor a tabela no código do aplicativo novamente.