Я бы сначала преобразовал таблицу matches
так:
SELECT
teamid = CASE t.calchometeam WHEN 1 THEN m.homeid ELSE m.outid END,
owngoal = CASE t.calchometeam WHEN 1 THEN m.homegoal ELSE m.outgoal END,
othergoal = CASE t.calchometeam WHEN 0 THEN m.homegoal ELSE m.outgoal END,
points = CASE m.homegoal
WHEN m.outgoal THEN @drawpoints
ELSE (SIGN(m.homegoal - m.outgoal) + 1) / 2 ^ ~m.playedhome) * @winpoints
+ (SIGN(m.homegoal - m.outgoal) + 1) / 2 ^ m.playedhome) * @losspoints
END
FROM matches m
CROSS JOIN (
SELECT CAST(0 AS bit) UNION ALL
SELECT CAST(1 AS bit)
) AS t (calchometeam)
WHERE m.matchdate <= @givendate
Теперь проще рассчитать необходимые итоги:
SELECT
teamid,
nomatches = COUNT(*),
owngoals = SUM(owngoal),
othergoals = SUM(othergoal),
points = SUM(points)
FROM transformed_matches
GROUP BY
teamid
Следующим шагом будет присоединение последнего набора результатов к таблице teams
, чтобы получить имена команд. И если вам действительно нужен этот последний шаг, вы, конечно, могли бы выполнять вычисления так, как вы планировали с самого начала, то есть рассчитывать только те статистические данные, которые вам нужны для вычитания из текущих значений, а не фактические показатели. Таким образом, используя эту инвертированную логику, весь запрос может выглядеть так:
WITH
transformed_matches AS (
SELECT
matchid = m.id,
teamid = CASE t.calchometeam WHEN 1 THEN m.homeid ELSE m.outid END,
owngoal = CASE t.calchometeam WHEN 1 THEN m.homegoal ELSE m.outgoal END,
othergoal = CASE t.calchometeam WHEN 0 THEN m.homegoal ELSE m.outgoal END,
points = CASE m.homegoal
WHEN m.outgoal THEN @drawpoints
ELSE (SIGN(m.homegoal - m.outgoal) + 1) / 2 ^ ~m.playedhome) * @winpoints
+ (SIGN(m.homegoal - m.outgoal) + 1) / 2 ^ m.playedhome) * @losspoints
END
FROM matches m
CROSS JOIN (
SELECT CAST(0 AS bit) UNION ALL
SELECT CAST(1 AS bit)
) AS t (calchometeam)
WHERE m.matchdate > @givendate
),
aggregated AS (
SELECT
teamid,
nomatches = COUNT(*),
owngoals = SUM(owngoal),
othergoals = SUM(othergoal),
points = SUM(points)
FROM transformed_matches
GROUP BY
teamid
)
SELECT
t.id,
t.name,
nomatches = t.nomatches - ISNULL(a.nomatches , 0),
owngoals = t.owngoals - ISNULL(a.orngoals , 0),
othergoals = t.nomatches - ISNULL(a.othergoals, 0),
points = t.points - ISNULL(a.points , 0)
FROM teams t
LEFT JOIN aggregated a ON t.id = a.teamid
Примечание. Вы не указали, какой тип футбола вы имели в виду, но, живя в Европе, мне было легче принять участие в футбольном матче, чем в любом другом виде. Тем не менее, поскольку я не был уверен, я решил параметризовать свой запрос. Вот почему вы можете видеть все эти @winpoints
, @drawpoints
и @losspoints
заполнители. Вы можете заменить переменные фактическими константами, если хотите, или оставить параметризованный запрос на тот случай, если вы хотите удовлетворить свое любопытство относительно того, каково было бы положение команды, если бы действовала другая система подсчета очков.