【问题标题】:Sqlite: select top x values for n usersSqlite:为 n 个用户选择前 x 个值
【发布时间】:2023-03-17 11:29:01
【问题描述】:

我有一个看起来像示例的 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 的情况下做到这一点?

【问题讨论】:

    标签: sqlite


    【解决方案1】:

    窗口函数是你的朋友(需要 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;
    

    【讨论】:

    • 哦,谢谢。似乎可行 :) 必须将用户重命名为 User01、User02 才能正确排序,但这没什么大不了的。
    【解决方案2】:

    你需要创建另一个表来存储输出结果,在我的例子中我称之为outputresult(user, score)

    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
    

    【讨论】:

    • 似乎 Sqlite 不支持 Declare 之类的东西,但可以在内存中创建一些临时表。好的,谢谢,我想过这样的想法,但我希望可能有一些棘手的查询可以轻松做到这一点。
    • 你可以走得更远...你可以创建一个表来存储我用 declare 语句声明的变量,但我不确定你想去那里.
    • 这不是远程有效的 sqlite 语法。
    猜你喜欢
    • 2013-01-25
    • 2011-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-05
    相关资源
    最近更新 更多