6

我正在开发一个包含记分卡系统的高尔夫应用程序。我将每个玩家的每个分数存储在数据库中,我需要提出一个查询来确定发球顺序。因此,例如,如果球员打了 3 个洞并且比分看起来像这样......

Player    1  2  3
--------- -  -  -
Player 1: 3, 4, 3
Player 2: 2, 3, 3
Player 3: 2, 4, 3

......那么订单需要看起来像这样......

1.) Player 2
2.) Player 3
3.) Player 1

...因此,球员将按照他们的分数与对手的分数进行比较。那有意义吗?这甚至可以通过查询实现,还是我应该编写一个函数来解析代码中的二维数组?在这种情况下,我使用的是 Java。

我的表结构如下所示:

  • 玩家(玩家 ID 和玩家姓名)
  • 回合(回合ID,课程ID)
  • 分数(回合编号、球员编号、洞数和分数)
4

3 回答 3

3

我可以看到一个解决方案,它使用 Windows 函数 row_number() 和数据库中的一个附加列来进行每个级别的排序(或 SQL Server 中的递归 CTE)。但是,SQLite 不支持这一点。

这是我在不进行大量向后查询的情况下实施解决方案的建议:

(1) 分配第一个发球台的发球台顺序。

(2) 对于每个下一个发球台,查看上一个得分和上一个发球台顺序:

(3) 通过按最高分数 DESC 和先前的开球顺序 ASC 排序,循环通过先前的分数来分配新的开球顺序。

因为你每轮只有几个玩家,所以在应用层这样做是合理的。但是,如果您有一个支持窗口函数的数据库,那么您可以更轻松地做一个仅数据库的解决方案。

我无法抗拒。这里有一些代码将使用一个表来存储订单。您需要循环通过,每个孔一次:

create table ThisOrder (
    ThisOrderId int primary key autoincrement,
    RoundId int,
    Hole int,
    PlayerId int
)

以某种顺序用每个玩家初始化它。

然后,为每个孔在表中插入新行:

insert into ThisOrder(RoundId, HoleId, PlayerId)
    select s.RoundId, s.Hole+1, s.PlayerId
    from Scores s join
         ThisOrder to
         on s.PlayerId = to.PlayerId and
            s.RoundId = to.RoundId and
            s.Hole = to.Hole
    order by s.Score DESC, to.Order ASC

你需要为每个洞调用一次,减去一个。

然后让您的订购为:

 select *
 from ThisOrder
 where roundid = <roundid> and hole = <thehole>
 order by ThisOrderId 
于 2012-05-15T17:58:11.897 回答
0

因此,您需要将每个球员在当前洞之前的每个洞的得分相加,然后按总得分对球员 ID 列表进行排序。

像这样的东西应该工作:

SELECT SUM(score) AS score, player_id FROM Scores WHERE round_id=$current_round AND hole_number<$current_hole GROUP BY player_id ORDER BY score;

这会生成一个包含两列(player_id 和 score)的结果表,其中包含与玩家数量一样多的行,将得分最高的玩家放在第一位。

于 2012-05-15T18:02:23.727 回答
0

此查询返回玩家得分最低的最高洞,并按以下顺序排列:

SELECT * FROM Players p
ORDER BY
  (SELECT MAX(s1.hole_number) FROM Scores s1
   LEFT JOIN Scores s2
     ON s2.round_id = s1.round_id AND
        s1.hole_number = s2.hole_number AND
        s2.score < s1.score
   WHERE s1.player_id = p.player_id AND
     s1.round_id = 1 AND s2.round_id IS NULL) DESC
于 2012-05-15T18:32:09.017 回答