Это действительно зависит от того, как структурированы ваши данные и каковы ваши ожидания. Я сделал предположение, что гоночные баллы основаны на позиции пилота, и что для каждой расы было определенное количество баллов.
Создание базовых таблиц.
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
баллов, если заканчивается в Позиции, которой не присвоено значение балла.
Вероятно, это можно было бы значительно упростить, если бы это было необходимо, но это могло бы ограничить способы, которыми мог бы расти запрос или приводить к дублированию данных. И снова, если ваши требования будут другими, эта структура, скорее всего, изменится.
дБ <> скрипка здесь
ПРИМЕЧАНИЕ: Вы также можете легко добавить общее количество баллов к вашему запросу:
Добавить 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