La reference à la colonne "USER_COUNT" n'est pas autorisée dans l'argument de la clause TOP

J'ai besoin d'aide sur un problème.

J'ai une table comme ça:

CREATE TABLE [dbo].[USER_ACTIONS] ( [ID] [int] IDENTITY(1,1) NOT NULL, [USER_ID] [int] NOT NULL, [ACTION_ID] [int] NOT NULL, [DEVICE_ID] [tinyint] NOT NULL [DATE] [datetime] NOT NULL, PRIMARY KEY CLUSTERED ([ID] ASC) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] 

Je souhaite conserver les 10 nouveaux loggings et GROUP BY USER_ID, ACTION_ID AND DEVICE_ID .

Voici ce que j'ai essayé:

 IF OBJECT_ID('tempdb..#TempUsers') IS NOT NULL DROP TABLE #TempUsers SELECT USER_ID, COUNT(USER_ID) as USER_COUNT INTO #TempUsers FROM USER_ACTIONS GROUP BY USER_ID, ACTION_ID,DEVICE_ID HAVING COUNT(USER_ID) > 10 ORDER BY USER_COUNT DELETE FROM USER_ACTIONS Actions WHERE ID IN (SELECT TOP (USER_COUNT - 10) ID FROM #TempUsers TMP WHERE Actions.USER_ID = TMP.USER_ID ORDER BY DATE ASC) 

Malheureusement, cela ne fonctionne pas et je reçois ce message:

La reference à la colonne "USER_COUNT" n'est pas autorisée dans l'argument de la clause TOP. Seules les references aux colonnes d'une scope externe ou aux expressions et sous-requêtes autonomes sont autorisées ici.

Je voudrais éviter les loops pour la performance.

Si quelqu'un a une idée, je serai très reconnaissant.

Merci beaucoup!

Vous pouvez simplement utiliser ROW_NUMBER() et supprimer où il est supérieur à 10 pour supprimer les lignes les plus anciennes et laisser les 10 plus récentes pour chaque combinaison

 DELETE t FROM ( SELECT *, RowNumber = ROW_NUMBER() OVER(PARTITION BY USER_ID, ACTION_ID,DEVICE_ID ORDER BY DATE DESC) FROM USER_ACTIONS ) AS t WHERE t.RowNumber > 10; 

Que diriez-vous:

 SELECT * , ROW_NUMBER() OVER (PARTITION BY a.USER_ID,a.ACTION_ID,a.DEVICE_ID ORDER BY a.DATE DESC) rn INTO #tmp FROM USER_ACTIONS a SELECT t.USER_ID, t.ACTION_ID, t.DEVICE_ID t.DATE FROM #tmp t WHERE t.rn <= 10