Please start any new threads on our new
site at https://forums.sqlteam.com. We've got lots of great SQL Server
experts to answer whatever question you can come up with.
Author |
Topic |
jkurzner
Starting Member
8 Posts |
Posted - 2012-04-30 : 10:11:29
|
I have a need to calculate soccer tables ("standings") for teams participating in a soccer league. I have been able to create the tables using total points as my ranking of teams with ties being broken by a series of tie breakers including score differntial, etc. My problem is that I need a way to compare head to head results as a tie breaking parameter. Here's a simplified structure and the current query that ranks the divisionsCREATE TABLE [dbo].[SCHEDULE]( [GNUM] [float] NULL, [DIVISION] [nvarchar](255) NULL, [FCODE] [nvarchar](255) NULL, [GDATE] [datetime] NULL, [HTEAM] [nvarchar](255) NULL, [VTEAM] [nvarchar](255) NULL, [PLAYED] [bit] NULL, [HRUNS] [float] NULL, [VRUNS] [float] NULL, [HFORFEIT] [bit] NULL, [VFORFEIT] [bit] NULL, [HCLUB] [nvarchar](255) NULL, [VCLUB] [nvarchar](255) NULL,) ON [PRIMARY]GO Presently there are two views that calculate the points because we allow for a maximum goal differential per game and also assign points to wins losses and ties. It's points that is the first ranking, then head-to-head, then maximum goal differential, etc. SELECT *, CASE WHEN GD > 3 THEN 3 WHEN GD < - 3 THEN - 3 ELSE GD END AS [MaxGD], CASE WHEN W = 1 THEN 3 WHEN D = 1 THEN 1 ELSE 0 END AS [Points]FROM (SELECT SCHEDULE.GNUM, SCHEDULE.DIVISION, SCHEDULE.HTEAM AS TeamID, CASE WHEN (Schedule.HRuns > Schedule.VRuns) OR (Schedule.VForfeit = 1) THEN 1 ELSE 0 END AS [W], CASE WHEN (Schedule.HRuns < Schedule.VRuns) AND (Schedule.VForfeit = 0) THEN 1 ELSE 0 END AS [L], CASE WHEN Schedule.HRuns = Schedule.VRuns THEN 1 ELSE 0 END AS [D], CASE WHEN Schedule.Hforfeit = 1 THEN 1 ELSE 0 END AS [Forfeit], Schedule.HRuns AS [GF], Schedule.VRuns AS [GA], Schedule.HRuns - Schedule.VRuns AS [GD], Teams.TCode, Teams.Team FROM SCHEDULE INNER JOIN TEAMS ON SCHEDULE.HTEAM = TEAMS.TCODE WHERE (SCHEDULE.PLAYED <> 0) AND (SCHEDULE.HFORFEIT = 0)) AS TUNIONSELECT *, CASE WHEN GD > 3 THEN 3 WHEN GD < - 3 THEN - 3 ELSE GD END AS [MaxGD], CASE WHEN W = 1 THEN 3 WHEN D = 1 THEN 1 ELSE 0 END AS [Points]FROM (SELECT SCHEDULE.GNUM, SCHEDULE.DIVISION, SCHEDULE.VTEAM AS TeamID, CASE WHEN (Schedule.HRuns < Schedule.VRuns) OR (Schedule.HForfeit = 1) THEN 1 ELSE 0 END AS [W], CASE WHEN (Schedule.HRuns > Schedule.VRuns) AND (Schedule.HForfeit = 0) THEN 1 ELSE 0 END AS [L], CASE WHEN Schedule.HRuns = Schedule.VRuns THEN 1 ELSE 0 END AS [D], CASE WHEN Schedule.Hforfeit = 1 THEN 1 ELSE 0 END AS [Forfeit], Schedule.VRuns AS [GF], Schedule.HRuns AS [GA], Schedule.VRuns - Schedule.HRuns AS [GD], Teams.TCode, Teams.Team FROM SCHEDULE, teams WHERE (Schedule.VTeam = Teams.TCode) AND (SCHEDULE.PLAYED <> 0) AND (SCHEDULE.VFORFEIT = 0)) AS TUNIONSELECT *, CASE WHEN GD > 3 THEN 3 WHEN GD < - 3 THEN - 3 ELSE GD END AS [MaxGD], 0 AS [Points]FROM (SELECT Schedule.gnum, Schedule.Division, Schedule.HTeam AS TeamID, 0 AS [W], 1 AS [L], 0 AS [D], 1 AS [Forfeit], 0 AS [GF], 3 AS [GA], - 3 AS [GD], Teams.TCode, Teams.Team FROM Schedule, Teams WHERE Schedule.HTeam = Teams.TCode AND Schedule.Played <> 0 AND HForfeit = 1) AS TUNIONSELECT *, CASE WHEN GD > 3 THEN 3 WHEN GD < - 3 THEN - 3 ELSE GD END AS [MaxGD], 0 AS [Points]FROM (SELECT Schedule.gnum, Schedule.Division, Schedule.VTeam AS TeamID, 0 AS [W], 1 AS [L], 0 AS [D], 1 AS [Forfeit], 0 AS [GF], 3 AS [GA], - 3 AS [GD], Teams.TCode, Teams.Team FROM Schedule, Teams WHERE Schedule.VTeam = Teams.TCode AND Schedule.Played <> 0 AND VForfeit = 1) AS TAnd here is the standings query which runs agains tht points query for creating the table viewsSELECT TOP (100) PERCENT DIVISION, TCode, Team, Wins, Losses, Draws, Forfeits, Points, GF, GA, MaxGD, Wins + Losses + Draws AS TotGms, CAST(Points / (Wins + Losses + Draws) AS decimal(6, 4)) AS AvgPts, CAST(MaxGD / (Wins + Losses + Draws) AS decimal(6, 4)) AS AvgGDFROM (SELECT DISTINCT TOP (100) PERCENT DIVISION, TCode, Team, SUM(W) AS Wins, SUM(L) AS Losses, SUM(D) AS Draws, SUM(Forfeit) AS Forfeits, CAST(SUM(Points) AS decimal(5, 0)) AS Points, SUM(GF) AS GF, SUM(GA) AS GA, CAST(SUM(MaxGD) AS decimal(5, 0)) AS MaxGD FROM dbo.PointsQuery GROUP BY DIVISION, TCode, Team ORDER BY DIVISION, Points DESC, MaxGD DESC) AS xORDER BY DIVISION, AvgPts DESC, AvgGD DESC Tables names are schedule, teams, clubs, division. Clubs have multiple teams and teams participate in divisions. Divisions basically hold the name of the division and the points for wins, ties, etc. Therefore it is possible for each division to have different rules for ranking the standings. Right now the rules are all the same for the competitive divisions with 3 points for a win, 1 for a draw and 0 for a loss. In addition there is also the ability to record a forfeit to both teams (i.e. bad behavior) where both teams lose. There is a maximum goal differential of + or - 3 for each game. Therefore, if a team wins 8-0 they only get a +3 goal differential for that game and the loser only gets a -3. The sum of the goal differentials is a tie-breaking component. As far as head-to-head; that tie-breaker comes immediately after the average points ranking. We use average points to rank the teams because sometimes they don't all play the same number of games.Tie-breakers in order is:Average PointsHead-to-HeadAvg Goal DifferentialMost winsFewest lossesFewest goals allowedI just can't get my head around a way to do the head-to-head comparison when teams have a tie in points. Also, for head-to-head when multiple teams are tied. |
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2012-04-30 : 10:14:30
|
please post some data and explain the points concept rather than posting the query. then explain what output you want to get------------------------------------------------------------------------------------------------------SQL Server MVPhttp://visakhm.blogspot.com/ |
 |
|
jkurzner
Starting Member
8 Posts |
Posted - 2012-04-30 : 12:11:42
|
Good points. Consider the following Team Wins Losses Draws Points AvgPts AvgGDTeam A 11 1 0 33 2.75 1.917Team B 11 1 0 33 2.75 1.833Team C 9 2 1 28 2.333 1.75Team D 8 3 1 25 2.083 1.333Team E 7 4 1 22 1.833 0.667Team F 6 3 3 21 1.75 0.917Team G 5 4 3 18 1.5 0.25 In the Above Example consider that Team B beat Team A in a head to head match and that was the only time they played each other. The order should be Team B then Team A Team Wins Losses Draws Points AvgPts AvgGDTeam A 10 2 0 30 3 1.917Team B 10 2 0 30 3 1.833Team C 10 2 0 30 3 1.75Team D 8 3 1 25 2.083 1.333Team E 7 4 1 22 1.833 0.667Team F 6 3 3 21 1.75 0.917Team G 5 4 3 18 1.5 0.25 In the above example Team A lost to both team B and team C. Team C beat team B. The order should be Team C Team B Team A The existing ranking is due to average points followed by average goal differential. I need head-to-head ranking to occur before the goal differential ranking. |
 |
|
yosiasz
Master Smack Fu Yak Hacker
1635 Posts |
Posted - 2012-04-30 : 12:48:51
|
you seem to be missing goals for and goals against. do you have that dataI am not sure if little league rules are different that the standard rules but tie breakers are resolved via goals for and goals against differential, are they not?<><><><><><><><><><><><><><><><><>If you don't have the passion to help people, you have no passion |
 |
|
yosiasz
Master Smack Fu Yak Hacker
1635 Posts |
Posted - 2012-04-30 : 13:05:17
|
declare @rankings table(Team varchar(255), Wins int, Losses int, Draws int, points int, AvgPts decimal(10,3), AvgGD decimal(10,3))insert into @rankingsselect 'Team A', 11, 1, 0, 33, 2.75, 1.917unionselect 'Team B', 11, 1, 0, 33, 2.75, 1.833unionselect 'Team C', 9, 2, 1, 28, 2.333, 1.75unionselect 'Team D', 8, 3, 1, 25, 2.083, 1.333unionselect 'Team E', 7, 4, 1, 22, 1.833, 0.667unionselect 'Team F', 6, 3, 3, 21, 1.75, 0.917unionselect 'Team G', 5, 4, 3, 18, 1.5, 0.25declare @gameswonlost table(WinnerTeam varchar(255), LoserTeam varchar(255))insert into @gameswonlostselect 'Team C', 'Team A'unionselect 'Team C', 'Team A'unionselect 'Team C', 'Team B'select * from @rankingsselect a.Team, COUNT(b.WinnerTeam) as winnerCount, AvgPts from @rankings a left join @gameswonlost b on a.Team = b.WinnerTeam group by a.Team,b.WinnerTeam, AvgPts ORDER BY COUNT(b.WinnerTeam) DESC<><><><><><><><><><><><><><><><><>If you don't have the passion to help people, you have no passion |
 |
|
jkurzner
Starting Member
8 Posts |
Posted - 2012-05-01 : 10:56:30
|
The goals for and goals against don't really matter for the purpose of tie breaking head-to-head since that fell below average goal differential and head-to-head. I left them out for the purpose of this example.In other words, unless head to head and average goal differential were the same, goals for or against would not be considered. Also, the league that I work with only allows a maximum goal differential of +3 or -3 per game and head-to-head is the second tie breaker |
 |
|
|
|
|
|
|