【问题标题】:SQL to Determine Tee Order in Golf ApplicationSQL 确定高尔夫应用程序中的发球顺序
【发布时间】:2012-05-15 17:34:50
【问题描述】:

我正在开发一个包含记分卡系统的高尔夫应用程序。我将每个玩家的每个分数存储在数据库中,我需要提出一个查询来确定发球顺序。因此,例如,如果球员打了 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)
  • 得分(回合 ID、球员 ID、洞数和得分)

【问题讨论】:

  • 排序是按总分还是按最后一洞,然后是前一洞等?
  • 排序将是之前的最低分数。因此,对于玩家 2,您可以看到他们在第 2 洞击败了其他两名玩家,因此玩家 2 将是第一个。然后继续返回(从第 2 洞开始,不计算球员 2),球员 3 在第 1 洞击败球员 1,这使得球员 3 排在第二位,导致球员 1 排在最后。这能把事情弄清楚吗?困惑我知道哈哈
  • 我建议你用java来做
  • 您如何旋转数据以获得第一组的结果?
  • @Keyser 我想这就是我要做的,但我想先看看是否可以通过查询...

标签: java sql database sqlite


【解决方案1】:

我可以看到一个解决方案,它使用 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 

【讨论】:

  • 我没有想到这一点,我喜欢这个解决方案,因为我可以随时查询 tee order 列。它是轻量级的,因为每次我想知道开球顺序时,它只是回顾以前的洞得分,而不是处理每个球员的每个得分。谢谢,我一定会考虑的。
  • 哈哈谢谢你的编辑,你肯定用这个赢得了我。我喜欢这种方法比我原来的想法要多得多。很好的解决方案,不胜感激。
【解决方案2】:

因此,您需要将每个球员在当前洞之前的每个洞的得分相加,然后按总得分对球员 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)的结果表,其中包含与玩家数量一样多的行,将得分最高的玩家放在第一位。

【讨论】:

  • 这样的事情是行不通的,因为我需要根据之前的最低分数与对手的分数进行排序,而不是不幸的总分。如果我想确定谁获胜,此方法将起作用。
【解决方案3】:

此查询返回玩家得分最低的最高洞并按此排序:

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

【讨论】:

  • 我了解您的意图,但不太明白。特别是如果只打了一个洞并且那个洞有平局,它就不知道如何确定正确的顺序(我对表格结构的错)。如果每个球员在每个洞的得分都不同,那么这将起作用。
  • @Alex_Hyzer_Kenoyer,我同意。使用原始顺序添加另一个 ORDER BY 表达式,例如 ORDER BY (...) DESC, player_order ASC
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-09-22
  • 1970-01-01
  • 2021-04-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多