如何使用密集排名并自动生成日期

时间:2016-06-03 15:50:57

标签: sql sql-server

我有两个关于DENSE_RANK的问题,另一个基于插入日期。基本上我有2个联赛,每个联赛有4支球队。每个联盟都有一轮像这样的赛程:

    League 1

    Week1: 1v4, 2v3  - Date: 10-June-2016
    Week2: 1v3, 2v4  - Date: 17-June-2016
    Week3: 1v2, 3v4  - Date: 24-June-2016

    League 2

    Week1: 5v8, 6v7 - Date: 10-June-2016
    Week2: 5v7, 6v8 - Date: 17-June-2016
    Week3: 5v6, 7v8 - Date: 24-June-2016

(They play each other home and away)
  • 好的,所以联赛1和联赛2是(LeagueID 1和League ID 2)
  • 第1周和第2周显示在WeekNumber列
  • 团队1 -8拥有自己的ID(TeamID,然后显示为HomeTeamID和AwayTeamID)
  • 日期进入FixtureDate

我的问题是:

1-如何根据WeekNumber设置它以便提及游戏组,它会注意到这些游戏属于第1周,第2周,第3周等游戏。

2-如何自动生成日期,以便在2016年6月10日播放第1周时,7天后播放下一轮灯具,7天后播放等等。

下面是目前的表格:

WeekNumber  HomeTeamID   AwayTeamID  FixtureWeek  LeagueID
1           1             4          NULL         1
1           1             3          NULL         1
1           1             2          NULL         1
1           2             3          NULL         1
1           2             4          NULL         1
1           3             4          NULL         1
1           5             8          NULL         2
1           5             7          NULL         2
1           5             6          NULL         2
1           6             7          NULL         2
1           6             8          NULL         2
1           7             8          NULL         2

以下是它应该的样子:

WeekNumber  HomeTeamID   AwayTeamID  FixtureWeek  LeagueID
1           1             4          10-06-2016         1
2           1             3          17-06-2016         1
3           1             2          24-06-2016         1
1           2             3          10-06-2016         1
2           2             4          17-06-2016         1
3           3             4          24-06-2016         1
1           5             8          10-06-2016         2
2           5             7          17-06-2016         2
3           5             6          24-06-2016         2
1           6             7          10-06-2016         2
2           6             8          17-06-2016         2
3           7             8          24-06-2016         2

以下是我当前需要修改的代码,但我需要帮助:

CREATE PROCEDURE [dbo].[Fixture_Insert]
 @LeagueID INT


AS
SET NOCOUNT ON
BEGIN

INSERT INTO dbo.Fixture (WeekNumber, HomeTeamID, AwayTeamID, FixtureWeek, LeagueID)
SELECT
    ROW_NUMBER() OVER (ORDER BY a.LeagueID) AS WeekNumber,
    h.TeamID,
    a.TeamID,
    NULL AS FixtureWeek, -- Don't know what to set this to for automatic dates
    h.LeagueID
FROM dbo.Team h
CROSS JOIN dbo.Team a
WHERE h.TeamID <> a.TeamID
AND h.LeagueID = a.LeagueID

END

更新:

我已应用图片来展示正在发生的事情,因此您可以看到需要做些什么来解决它(显示的表格是我从dbo.Fixture中选择*时):

enter image description here

上面显示的上述处理程序显示在此处:

enter image description here

2 个答案:

答案 0 :(得分:1)

DECLARE @StartFixtureWeek date = '2016-06-10'

;WITH team AS (
SELECT *
FROM (VALUES
(1,1),(2,1),(3,1),(4,1),(5,2),(6,2),(7,2),(8,2)
) as t (teamid, leagueid)
)
, cte AS (
SELECT  h.teamid AS HomeTeamID,
        a.teamid AS AwayTeamID,
        h.leagueid AS LeagueID
FROM team h
CROSS JOIN team a
WHERE h.teamid != a.teamid AND h.leagueid = a.leagueid
), final AS (
SELECT  ROW_NUMBER() OVER (PARTITION BY c.LeagueID  ORDER BY c.LeagueID, c.HomeTeamID, c.AwayTeamID) as rn,
        c.HomeTeamID,
        c.AwayTeamID,
        c.LeagueID
FROM cte c 
CROSS APPLY (
    SELECT TOP 1 a.HomeTeamID, a.AwayTeamID 
    FROM cte a 
    WHERE a.LeagueID= c.LeagueID and a.AwayTeamID=c.HomeTeamID and a.HomeTeamID =c.AwayTeamID
    ORDER BY a.HomeTeamID, a.LeagueID) as b
WHERE c.HomeTeamID < b.HomeTeamID
)

SELECT  CASE WHEN rn > 3 THEN rn-3 ELSE rn END as WeekNumber,
        HomeTeamID,
        AwayTeamID,
        CAST(DATEADD(week,(CASE WHEN rn > 3 THEN rn-3 ELSE rn END)-1,@StartFixtureWeek) as date) FixtureWeek,
        LeagueID
FROM final

输出:

WeekNumber           HomeTeamID  AwayTeamID  FixtureWeek LeagueID
-------------------- ----------- ----------- ----------- -----------
1                    1           2           2016-06-10  1
2                    1           3           2016-06-17  1
3                    1           4           2016-06-24  1
1                    2           3           2016-06-10  1
2                    2           4           2016-06-17  1
3                    3           4           2016-06-24  1
1                    5           6           2016-06-10  2
2                    5           7           2016-06-17  2
3                    5           8           2016-06-24  2
1                    6           7           2016-06-10  2
2                    6           8           2016-06-17  2
3                    7           8           2016-06-24  2

(12 row(s) affected)

答案 1 :(得分:0)

向名为@StartFixtureWeek DATETIME

的存储过程添加参数

然后您可以使用DATEADD

CREATE PROCEDURE [dbo].[Fixture_Insert]
 @LeagueID INT,
 @StartFixtureWeek DATETIME


AS
SET NOCOUNT ON
BEGIN

INSERT INTO dbo.Fixture (WeekNumber, HomeTeamID, AwayTeamID, FixtureWeek, LeagueID)
SELECT
    ROW_NUMBER() OVER (ORDER BY a.LeagueID) AS WeekNumber,
    h.TeamID,
    a.TeamID,
    SELECT DATEADD(day,(ROW_NUMBER() OVER (ORDER BY a.LeagueID)-1)*7,@StartFixtureWeek) AS FixtureWeek, 
    h.LeagueID
FROM dbo.Team h
CROSS JOIN dbo.Team a
WHERE h.TeamID <> a.TeamID
AND h.LeagueID = a.LeagueID

END