1

我有一个这样的 sqlite3 表:

sqlite> select * from scores;
team        Name        score
----------  ---------   ----------
A           Name1       93
A           Name2       96
A           Name3       78
A           Name4       82
B           Name5       83
B           Name6       30
B           Name7       99
B           Name8       71
B           Name8A      45
B           Name8C      70
c           Name9       87
c           Name10      87
c           Name11      81
c           Name12      71
c           Name13      91

有很多团队(大约30个团队),每个团队有很多成员(实际记录超过10,000条)。我只想像这样获得每个团队的前 N ​​个获胜者(为简化起见,在此示例中 N = 3):

A     Name2   96
A     Name1   93
A     Name4   82
B     Name7   99
B     Name5   83
B     Name8   71
C     Name13  91
C     Name9   87
C     Name10  87

他们在同一支球队中的得分排名。

如何使用 sqlite3 查询得到这个结果?任何人都可以提供一些线索?非常感谢。

顺便说一句,“名称”字段不是唯一的,只有(团队,名称)是唯一的,这意味着相同的名称可以出现在不同的团队中。

4

3 回答 3

0

scores我们可以从一个表中选择包含每个团队的前 N ​​个结果的结果集,而不是从表中选择每个团队的前 N ​​个结果。

让我们将具有我们需要的数据的表称为leaderboard,其结构等于scores

我们将插入到 的数据复制scoreleaderboard。然后我们只保留每支球队最好的 N 个分数,并leaderboard从中删除任何不够高的分数。为此,我们需要一个触发器,如下所示:

CREATE TRIGGER "update_top_scores"
AFTER INSERT ON scores  
BEGIN
    -- Add the record to leaderboard
    INSERT INTO leaderboard (team, name, score) VALUES (NEW.team, NEW.name, NEW.score);
    -- only keep the top 30 records of each teams 
    DELETE FROM leaderboard WHERE team = NEW.team AND name NOT IN (SELECT name FROM leaderboard WHERE team = NEW.team ORDER BY score DESC LIMIT 30);

END

所以现在我们可以使用一个简单的查询从每个团队中获得前 N 个分数

SELECT * FROM leaderboard;

假设您不想在 db 文件中有新表或触发器,我建议您执行以下操作

  1. 创建新表leaderboarddummy_scores
  2. 创建触发器dummy_scores
  3. use语句将数据从toINSERT INTO ... SELECT复制,这也激活了触发器scoredummy_score
  4. 得到结果SELECT * FROM leaderboard
  5. drop leaderboarddummy_scores以及来自 db 文件的触发器

现在你有了原始的 db 文件和你需要的结果。

于 2016-07-28T08:31:16.013 回答
0

你可以试试这个

set @currcount=0,@currvalue='', @N=4;
SELECT team, Name, score FROM ( SELECT team, Name, score, @currcount :=    
IF(@currvalue = team, @currcount + 1, 1) as rank, @currvalue := team FROM 
scores ORDER BY team DESC) as what WHERE rank<@N order by team asc, score desc
于 2016-07-26T10:32:11.617 回答
0

根据问题:如何选择每组的前 N ​​行?,戈登林诺夫的方法,我想出了这段代码:

select * from dayobs a 
     where a.rowid in 
     (select b.rowid from dayobs b where b.station==a.station order by b.rain desc limit 5);

它可以工作,但非常非常慢,sqlite 给每条记录超过 1 分钟!此查询大约需要半小时才能完成。显然,这在实际工作中是不可能发生的。我认为必须有一些方法可以更有效地做到这一点。

于 2016-07-27T00:57:56.377 回答