Sqlite: выберите лучшие значения x для n пользователей - PullRequest
0 голосов
/ 06 марта 2019

У меня есть таблица Sqlite DB (тест), которая выглядит как пример:

User Score

Пользователь выглядит как Пользователь1, Пользователь2 ... Пользователь 20

Счет - целое число.

Пример:

User1 204
User2 5555
User6 102
etc.

Как можно выбрать, скажем, 3 верхних значения для каждого существующего пользователя, упорядоченного по счету?Например:

User1 4344
User1 4000
User1 2330
User2 2300
User2 1000
User2 300
User3 555
User3 100
User3 10
User4 2033
...

Это дает мне только топ 3 всех пользователей.

  SELECT user, score FROM test ORDER BY score DESC limit 3

Это дает мне всех пользователей, но только одно верхнее значение.

  SELECT user, score FROM test GROUP BY user ORDER BY score DESC

Единственное решение, которое я нашел до сих пор, - это добавить всех пользователей в список и использовать цикл (я работаю с Python).Каждый раз анализируется один пользователь.Но мне любопытно, можно ли это сделать без цикла и только с помощью Sqlite?

Ответы [ 2 ]

0 голосов
/ 06 марта 2019

Оконные функции - ваш друг (требуется 3.25 или новее):

SELECT user, score
FROM (SELECT user, score,
             row_number() OVER (PARTITION BY user ORDER BY score DESC) AS rn
       FROM test)
WHERE rn <= 3
ORDER BY user, score DESC;
0 голосов
/ 06 марта 2019

Вам нужно создать другую таблицу для хранения результата вывода, в моем примере я назвал ее outputresult (пользователь, оценка) :

Declare     @duser nvarchar(30)
Declare     @duser2 nvarchar(30)
Declare     @dscore int

DECLARE cur1 CURSOR FOR
select distinct [user] from TOP3s



OPEN cur1

FETCH NEXT FROM cur1 INTO @duser

WHILE @@Fetch_Status = 0 

BEGIN

Declare cur2 Cursor FOR
select top (3) [user], score from TOP3s where [user] = @duser order by [user], score desc
OPEN cur2

fetch next from cur2 into @duser2, @dscore

WHILE @@Fetch_Status = 0 

begin

insert into outputresult values(@duser2, @dscore)

fetch next from cur2 into @duser2, @dscore

end

close cur2
deallocate cur2


FETCH NEXT FROM cur1 INTO @duser

end

close cur1

Deallocate cur1


--you can run this query to check the output:
select * from outputresult
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...