1

トーナメント関連のデータベースに2つのテーブルがあり、正しい全体的な結果を生成するには、最も最適化された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はそれを返す必要はありませんが、参照用に表示しています。

私が持っている最も近いクエリはこれですが、nTournamentID#25の「nEventLog」テーブルにレコードがないため、「チームB」は返されません。

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クエリの専門家ではありません。また、これに2日間取り組んできましたが、あまり成功していません。ご協力いただければ幸いです。

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などを表すためにnullをフォーマットできます。

于 2013-03-22T14:47:33.900 に答える