1

我在与锦标赛相关的数据库中有两个表,我需要知道最优化的 SQL 查询以生成正确的整体结果。结果必须显示总得分,减去任何处罚,并且应根据首先达到该分数的人打破并列的分数。

在数据库表中,我有一个事件日志,其中每个分数都是随着球队进行锦标赛而添加的,我还有另一个表,显示哪个球队是哪个锦标赛的一部分。

Table "xTournamentTeam" (connects a team to a tournament)
=======================
+-----+------------+--------+--------------+
| nID | Team Name  | TeamID | TournamentID |
+-----+------------+--------+--------------+
|  1  | Team A     | 12     | 25           |
|  2  | Team B     | 13     | 25           |
|  3  | Team C     | 14     | 25           |
|  4  | Team D     | 15     | 25           |
|  3  | Team A     | 12     | 32           |
|  4  | Team B     | 13     | 32           |
+-----+------------+--------+--------------+

Table "nEventLog" (records scoring during a tournament)
=================
+-----+---------------+---------+----------+----------------+-----------------------+
| nID | nTournamentID | nTeamID | nPoints  | nPointsPenalty | nEventTime            |
+-----+---------------+---------+----------+----------------|-----------------------+
|  1  | 25            | 15      | 100      | 0              | 1/24/2013 6:05:14 AM  |
|  2  | 25            | 14      | 100      | 0              | 1/24/2013 6:29:55 AM  |
|  3  | 25            | 14      | 100      | 25             | 1/24/2013 7:09:34 AM  |
|  4  | 25            | 12      | 100      | 0              | 1/24/2013 7:12:28 AM  |
|  5  | 25            | 12      | 100      | 0              | 1/24/2013 8:42:59 AM  |
|  6  | 25            | 12      | 100      | 50             | 1/24/2013 8:43:36 AM  |
|  7  | 25            | 14      | 100      | 0              | 1/24/2013 9:15:24 AM  |
|  8  | 25            | 15      | 100      | 0              | 1/24/2013 9:15:27 AM  |
|  9  | 32            | 12      | 100      | 0              | 1/28/2013 8:33:49 AM  |
|  10 | 32            | 13      | 100      | 25             | 1/28/2013 2:15:12 PM  |
|  11 | 32            | 12      | 100      | 10             | 1/28/2013 7:12:25 AM  |
|  12 | 32            | 13      | 100      | 0              | 1/29/2013 7:18:06 AM  |
+-----+---------------+---------+----------+----------------+-----------------------+

在上述数据的情况下,我需要的查询应该为锦标赛 #25 生成以下结果:

+-------+------------+--------+--------------+---------------+---------------------+-----------------------------+
| nRank | Team Name  | TeamID | TournamentID | nTotalPoints  | nTotalPointsPenalty | nLatestEventTime            |
+-------+------------+--------+--------------+---------------+---------------------+-----------------------------+
|  1    | Team A     | 12     | 25           | 300           | 50                  | 1/24/2013 8:43:36 AM        |
|  2    | Team C     | 14     | 25           | 300           | 25                  | 1/24/2013 9:15:24 AM        |
|  3    | Team D     | 15     | 25           | 200           | 0                   | 1/24/2013 9:15:27 AM        |
|  4    | Team B     | 13     | 25           | 0             | 0                   |                             |
+-------+------------+--------+--------------+---------------+---------------------+-----------------------------+

出于加载目的,我试图不惜一切代价避免子查询,因为最终查询应尽可能优化。“nRank”列可以以编程方式生成...... MySQL 不应该返回它,但我将它作为参考。

我最接近的查询是这个,但它不返回“Team B”,因为他们在 nTournamentID #25 的“nEventLog”表中没有任何记录:

SELECT xTournamentTeam.nTeamName
     , sum(nEventLog.nPoints) AS nTotalPoints
     , xTournamentTeam.nTeamID
     , max(nEventLog.nEventTime) AS nLatestEventTime
     , sum(nEventLog.nPointsPenalty) AS nTotalPenaltyPoints
     , xTournamentTeam.nTournamentID
FROM
  xTournamentTeam
LEFT OUTER JOIN nEventLog
ON xTournamentTeam.nTeamID = nEventLog.nTeamID
WHERE
  xTournamentTeam.nTournamentID = 33
  AND nEventLog.nTournamentID = 33
GROUP BY
  xTournamentTeam.nID
, xTournamentTeam.nTournamentID
ORDER BY
  nTotalPoints DESC
, nLatestEventTime DESC

我当然不是 MySQL 查询方面的专家,而且我已经为此工作了两天,但没有取得多大成功,因此将不胜感激。

4

1 回答 1

1

我稍微改变了你的逻辑,我认为它有效:

SELECT
          xTournamentTeam.TeamName
         , sum(nEventLog.nPoints) AS nTotalPoints
         , xTournamentTeam.TeamID
         , max(nEventLog.nEventTime) AS nLatestEventTime
         , sum(nEventLog.nPointsPenalty) AS nTotalPenaltyPoints
         , xTournamentTeam.TournamentID
FROM
      xTournamentTeam 
LEFT OUTER JOIN nEventLog
    ON xTournamentTeam.TournamentID = nEventLog.nTournamentID AND xTournamentTeam.TeamID = nEventLog.nTeamID
WHERE
      xTournamentTeam.TournamentID = 25          
GROUP BY
      xTournamentTeam.TeamID
    , xTournamentTeam.TournamentID 
    , xTournamentTeam.TeamName
ORDER BY 
    nTotalPoints DESC

如果需要,您可以格式化空值以表示 0 或其他内容。

于 2013-03-22T14:47:33.900 回答