赛车成绩数据库(设计问题)

时间:2018-11-07 18:16:57

标签: sql sql-server database database-design sql-server-2014

我正在创建一个Motorsports数据库,但是在其中一种数据库表设计中遇到了一些困难。

问题

每轮比赛都有两场比赛,他们有不同的积分系统。截至目前,我正在存储每场比赛的每行积分(介于20到30之间),但这 这很耗时,而且如果我将来要更改它们,那么更新它们将很头疼。

我可以保持原样,但是想要一个更好的解决方案。

第1种族示例 :(位置驱动因素-点)

  1. 驱动程序1-20
  2. 驱动程序2-15
  3. 驱动程序3-10
  4. 驱动程序4-5

第2种族示例 :(位置驱动因素-点)

  1. 驱动程序1-10
  2. 驱动程序2-8
  3. 驱动程序3-6
  4. 驱动程序4-3

我想要一个可以具有不同积分系统的表,之后可以将其加入结果表,因此我不必每次比赛都手动存储积分。

必须存储PointsSystemID,Position,Points的表。

有人对如何执行此操作有任何想法吗?

注意:我正在使用SQL Server 2014

2 个答案:

答案 0 :(得分:0)

您可以完全创建问题(PointsSystemID, Position, Points)中建议的表

然后在结果表中,将Points替换为PointsSystemID

然后在SELECT时计算积分,只需将PointsSystemIDPosition上的两个表连接起来,就可以得到每场比赛中每个车手的积分。

答案 1 :(得分:0)

这实际上取决于数据的结构和期望。我假设比赛积分基于驾驶员的位置,并且每次比赛每个位置都有一定数量的积分。

创建基表。

CREATE TABLE DriverDetails ( DriverID int, DriverName varchar(100) ) ;
CREATE TABLE RaceDetails ( RaceID int, RaceDetails varchar(200) ) ;
CREATE TABLE PointSystems ( PointSystemID int, PositionID int, PointsAwarded int ) ;

我拆分了结构的主要部分,以便您可以添加有关每个部分的详细信息而无需重复数据。我还根据位置添加了点值。可以为每个种族更改积分值,并且可以将积分组分配给不同的种族而不必重复。

创建主要结果表。

CREATE TABLE ref_RaceRounds ( 
    RaceRoundID int
  , RaceID int
  , DriverID int
  , DriverPositionID int
  , PointSystemID int 
) ;

此表实质上是每场比赛的结果。如果需要,可以根据需要创建另一个RoundInfo型表来保存有关回合的信息。这也是定义用于比赛的PointSystem的地方。如果比赛以后更改了积分系统,则将保留历史积分。如果在比赛改变积分系统时将调整驾驶员积分,则可以将PointSystemID移至RaceDetails,并且可以调整JOIN

填充一些数据。

INSERT INTO DriverDetails (DriverID, DriverName)
VALUES (1,'Driver1'),(2,'Driver2'),(3,'Driver3'),(4,'Driver4'),(5,'SlowPoke') ;

INSERT INTO RaceDetails (RaceID, RaceDetails)
VALUES ( 1, 'Race1' ), ( 2, 'Race2' ) ;

/* This is assuming Driver Points are calculated by Race Position */
INSERT INTO PointSystems (PointSystemID, PositionID, PointsAwarded)
VALUES 
    ( 1, 1, 20 )
  , ( 1, 2, 15 )
  , ( 1, 3, 10 )
  , ( 1, 4,  5 )
  , ( 1, 5,  1 )
  , ( 2, 1, 10 )
  , ( 2, 2,  8 )
  , ( 2, 3,  6 )
  , ( 2, 4,  3 )
  , ( 2, 5,  1 )
;

/* Race Statistics by Driver */
INSERT INTO ref_RaceRounds ( RaceRoundID, RaceID, DriverID, DriverPositionID, PointSystemID)
VALUES
    (1,1,1,1,1)
  , (1,1,2,2,1)
  , (1,1,3,3,1)
  , (1,1,4,4,1)
  , (1,1,5,20,1)
  , (2,2,1,1,2)
  , (2,2,2,2,2)
  , (2,2,3,3,2)
  , (2,2,4,4,2)
  , (2,2,5,40,2)
;

以我设置积分的方式,如果驾驶员完成了没有积分值的排名,那么该驾驶员将获得null积分,可以转换为0在最终查询中。

现在通过联接这些表进行查询。

SELECT rrr.RaceRoundID
    , rd.RaceDetails
    , rrr.DriverID
    , dd.DriverName
    , rrr.DriverPositionID
    , ISNULL(ps.PointsAwarded,0) AS PointsAwarded
FROM ref_RaceRounds rrr
INNER JOIN DriverDetails dd ON rrr.DriverID = dd.DriverID
INNER JOIN RaceDetails rd ON rrr.RaceID = rd.RaceID
LEFT OUTER JOIN PointSystems ps ON rrr.PointSystemID = ps.PointSystemID
    AND rrr.DriverPositionID = ps.PositionID
    AND rrr.DriverID = dd.DriverID

哪个给:

RaceRoundID | RaceDetails | DriverID | DriverName | DriverPositionID | PointsAwarded
----------: | :---------- | -------: | :--------- | ---------------: | ------------:
          1 | Race1       |        1 | Driver1    |                1 |            20
          1 | Race1       |        2 | Driver2    |                2 |            15
          1 | Race1       |        3 | Driver3    |                3 |            10
          1 | Race1       |        4 | Driver4    |                4 |             5
          1 | Race1       |        5 | SlowPoke   |               20 |             0
          2 | Race2       |        1 | Driver1    |                1 |            10
          2 | Race2       |        2 | Driver2    |                2 |             8
          2 | Race2       |        3 | Driver3    |                3 |             6
          2 | Race2       |        4 | Driver4    |                4 |             3
          2 | Race2       |        5 | SlowPoke   |               40 |             0

我使用ISNULL(ps.PointsAwarded,0)LEFT OUTER JOIN来确保驾驶员在未分配点值的位置上获得0点。

如果需要,可以将其简化很多,但是它可能会限制查询的增长方式或导致重复数据的方式。同样,如果您的要求不同,则此结构可能会更改。

db <>提琴here

注意:您还可以轻松地向您的查询中添加“总运行点数”:

  • RaceDate添加到RaceDetails

  • , SUM(ISNULL(ps.PointsAwarded,0)) OVER(PARTITION BY rrr.DriverID ORDER BY rd.RaceDate ROWS UNBOUNDED PRECEDING) AS PointsAwarded_RunningTotal添加到SELECT

https://dbfiddle.uk/?rdbms=sqlserver_2014&fiddle=e477dbd2e978f685da59d548d1fe3b15