Genom att använda två användarvariabler och räkna samma på varandra följande store_id kan du ersätta <= 5
med vilken gräns du vill
SELECT a.*
FROM (
SELECT store_id, user_id, count(1) as visits
FROM shopping
WHERE store_id IN (60,61,62,63,64,65,66)
GROUP BY store_id, user_id
ORDER BY store_id, visits desc, user_id
) a,
(SELECT @prev:=-1, @count:=1) b
WHERE
CASE WHEN @prev<>a.store_id THEN
CASE WHEN @prev:=a.store_id THEN
@count:=1
END
ELSE
@count:[email protected]+1
END <= 5
Redigera som begärt någon förklaring:
Den första underfrågan (a) är den som grupperar och ordnar data så att du får data som:
store_id | user_id | visits
---------+---------+-------
60 1 5
60 2 3
60 3 1
61 2 4
61 3 2
den andra underfrågan (b) init användarvariabeln @prev
med -1 och @count
med 1
sedan väljer vi all data från underfrågan (a) som verifierar villkoret i case
.
-
verifiera att föregående store_id (
@prev
) vi har sett skiljer sig från det nuvarande store_id. Sedan den första@prev
är lika med -1 finns det inget som matchar det aktuella butiks-id så villkoret<>
är sant vi anger då är det andra fallet som bara tjänar till att ändra värdet@prev
med nuvarande butiks-id. Detta är tricket så att jag kan ändra de två användarvariablerna@count
och@prev
i samma skick. -
om föregående store_id är lika med
@prev
öka bara@count
variabel. -
vi kontrollerar att antalet är inom det värde vi vill ha så
<= 5
Så med våra testdata:
step | @prev | @count | store_id | user_id | visits
-----+-------+--------+----------+---------+-------
0 -1 1
1 60 1 60 1 5
2 60 2 60 2 3
3 60 3 60 3 1
4 61 1 61 2 4
5 61 2 61 3 2