Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-cloud-platform/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 在cte中使用DATEADD()_Sql_Sql Server - Fatal编程技术网

Sql 在cte中使用DATEADD()

Sql 在cte中使用DATEADD(),sql,sql-server,Sql,Sql Server,我试图在我的代码中使用DATEADD()函数,其中对于每个“周数”,我们应用一个日期,然后为下一周数添加7天。我遇到的问题是,如果我尝试以下代码: DATEADD(day,(ROW_NUMBER() OVER (ORDER BY LeagueID)-1)*7,@StartFixtureWeek) AS FixtureDate 它显示每一行的新日期,并且由于每周有六行分配给它们(分配的行数将来可能会改变),因此它不是每一行说明'week\u number'1和FixtureDate'01-09-

我试图在我的代码中使用DATEADD()函数,其中对于每个“周数”,我们应用一个日期,然后为下一周数添加7天。我遇到的问题是,如果我尝试以下代码:

DATEADD(day,(ROW_NUMBER() OVER (ORDER BY LeagueID)-1)*7,@StartFixtureWeek) AS FixtureDate
它显示每一行的新日期,并且由于每周有六行分配给它们(分配的行数将来可能会改变),因此它不是每一行说明
'week\u number'1和FixtureDate'01-09-2016'
,而是说明
'week\u number'1的第一行说明FixtureDate'01-09-2016'
,然后,第二行的“周数1”有固定日期“08-09-2016”,依此类推

“周号”1的固定日期应为“01-09-2016”,然后“周号”2的固定日期应为“08-09-2016”,然后“周号”3的固定日期应为“15-09-2016”,依此类推

如果我尝试这样做:

DATEADD(day,(ROW_NUMBER() OVER (ORDER BY LeagueID, week_number)-1)*7,@StartFixtureWeek) AS FixtureDate,
不显示任何结果

下面是我目前使用的DATEADD()函数的代码(从底部算起的第14行)。实际上,我需要它精确地处理我的“Week_number”的工作方式,而不是FixtureDate

更新:

   WITH League_Teams AS (
        -- Generate a unique-per-league index for each team that is between 0
        -- and the (number of teams - 1) and calculate the number of teams
        -- if this is an odd number then generate a fake team that's 0.
        SELECT TeamID AS id,
            LeagueID,
            ROW_NUMBER() OVER ( PARTITION BY LeagueID ORDER BY TeamID ) - 1 AS idx,
            0 AS is_fake,
            COUNT(1) OVER ( PARTITION BY LeagueID ) AS num_teams, 
            (COUNT(1) OVER ( PARTITION BY LeagueID ) % 2) AS num_fake
        FROM Team

        UNION ALL
        -- Insert a fake team if required
        SELECT NULL,
            LeagueID,
            COUNT(1),
            1,
            COUNT(1),
            1
        FROM   Team
        GROUP BY LeagueID
        HAVING COUNT(1) % 2  > 0
    ),
    cte AS (
        -- Calculate round 1 games
        SELECT 
            idx AS home_idx,
            num_teams + num_fake - 1 - idx AS away_idx,
            1 AS week_number,

            LeagueID AS leagueID,
            num_teams AS num_teams,
            num_fake AS num_fake
        FROM   league_teams
        WHERE  2 * idx < num_teams

        UNION ALL

        --  Generate successive rounds with the two cases when the away team has the maximum index or otherwise.
        SELECT 
            CASE away_idx
            WHEN num_teams + num_fake - 1 THEN home_idx + 1
            ELSE (home_idx + 1) % (num_teams + num_fake -1)
            END,

            CASE away_idx
            WHEN num_teams + num_fake - 1 THEN away_idx
            ELSE (away_idx + 1) % (num_teams + num_fake - 1)
            END,
            week_number + 1,
            leagueID,
            num_teams,
            num_fake
        FROM  cte
        WHERE week_number < (num_teams + num_fake - 1)
    )
    INSERT INTO dbo.Fixture
    -- Join the cte results back to the League_Teams table to convert
    -- Indexes used in calculation back to the actual team ids.
    SELECT rn,
           week_number,
           DATEADD(day,(ROW_NUMBER() OVER (ORDER BY week_number)-1)*7,@StartFixtureWeek) AS WeekNumber,
           h.id,
           a.id,
           c.leagueid
    FROM (
        SELECT ROW_NUMBER() OVER (ORDER BY LeagueID, week_number)  AS rn,
            t.*
        FROM (
               -- Duplicate the results swapping home and away.
               SELECT week_number,
                      home_idx,
                      away_idx,
                      LeagueId
               FROM   cte

               UNION ALL

               SELECT week_number + num_teams + num_fake - 1,
                      away_idx,
                      home_idx,
                      LeagueId
               FROM   cte
        ) t
    ) c
    INNER JOIN League_Teams h  ON ( c.home_idx = h.idx AND c.leagueId = h.LeagueID )
    INNER JOIN League_Teams a ON ( c.away_idx = a.idx AND c.leagueId = a.LeagueID )
    ORDER BY rn;

    select * from dbo.Fixture
    where LeagueID = 1  
小组:

固定装置:

[FixtureID] INT IDENTITY(1,1) NOT NULL PRIMARY KEY,
[WeekNumber] INT NOT NULL,
[FixtureDate] DATE NULL,
[HomeTeamID] TINYINT NULL,
[AwayTeamID] TINYINT NULL,
[LeagueID] TINYINT CONSTRAINT FK_Fixture_League FOREIGN KEY REFERENCES League(LeagueID)
数据:

联盟:

[LeagueID] TINYINT IDENTITY(1,1) NOT NULL PRIMARY KEY, 
[LeagueName] VARCHAR(30) UNIQUE
1, 'English Premiership'
2, 'English Division 1'
小组:

1, 'BCN', 'FC Barcelona', 1
2, 'MAD', 'Real Madrid', 1
3, 'ATH', 'Athletico Madrid', 1
4, 'ESP', 'Espanyol', 1
5, 'MAN', 'Manchester United', 2
6, 'BOL', 'Bolton', 2
7, 'CHE', 'Chelsea', 2
8, 'ARS', 'Arsenal', 2
下面是“Fixture”表的当前输出,正如您所看到的,日期是不正确的,因为它给出了一个星期的不同日期,而很明显,它们每周应该是相同的日期


我已经注释掉了许多额外的细节,以使其独立工作

    DECLARE @StartFixtureWeek datetime
SET @StartFixtureWeek = '2016-03-01';
WITH cte AS (
    -- Calculate round 1 games
    SELECT 
        --idx AS home_idx,
        --num_teams + num_fake - 1 - idx AS away_idx,
        1 AS week_number
       --,
        --LeagueID AS leagueID,
        --num_teams AS num_teams,
        --num_fake AS num_fake
 --   FROM   league_teams
   -- WHERE  2 * idx < num_teams
    UNION ALL
--  Generate successive rounds with the two cases when the away team has the maximum index or otherwise.
        SELECT 
            --CASE away_idx
            --WHEN num_teams + num_fake - 1 THEN home_idx + 1
            --ELSE (home_idx + 1) % (num_teams + num_fake -1)
            --END,
            --CASE away_idx
            --WHEN num_teams + num_fake - 1 THEN away_idx
            --ELSE (away_idx + 1) % (num_teams + num_fake - 1)
            --END,
            week_number + 1
          --,
            --LeagueID,
            --num_teams,
            --num_fake
        FROM  cte
        WHERE week_number < 10
       --(num_teams + num_fake - 1)
    )
   -- INSERT INTO dbo.Fixture
    -- Join the cte results back to the League_Teams table to convert
    -- Indexes used in calculation back to the actual team ids.
    SELECT rn,
           week_number,
           DATEADD(day,(ROW_NUMBER() OVER (ORDER BY --LeagueID,
          week_number)-1)*7,@StartFixtureWeek)  AS FixtureDate
         --,
           --h.id,
           --a.id,
           --c.leagueid
    FROM (
        SELECT ROW_NUMBER() OVER (ORDER BY --LeagueID,
        week_number)  AS rn,
            t.*
        FROM (
               -- Duplicate the results swapping home and away.
               SELECT week_number
            --,
                      --home_idx,
                      --away_idx,
                      --LeagueId
               FROM   cte)  t) a
这就是你想要的吗


您的示例中缺少了一些打字错误,我必须添加这些错误才能使其正常工作。这可能是您的问题,或者您仍然会遇到问题,在这种情况下,我将再次尝试在

中根据您的问题添加一些详细信息。我假设在FixtureDate列中,您希望显示本周开始的日期。如果这就是为什么要使用
行数()

我想这就是你所追求的:

DATEADD(week, week_number - 1, @StartFixtureWeek) AS FixtureDate
在您的查询代码中,它将显示如下(我已输入CTE和FROM子句query):


你能展示联盟球队的结构和内容吗,这样我就可以测试完整版本了?嗨,迈克,谢谢你的回答。这就是我想要的,如果它是一个独立的,但是如果我用我的完整代码和完整的赛程表输出它,它仍然会出现同样的问题。我已经更新了问题,包括完整的代码,table“Fixture”表的架构、数据和当前输出,以便您可以看到正在发生的情况。如果您能再次尝试,我将不胜感激,因为我相信您将知道如何解决此问题:)请显示预期结果。根据您的问题,我假设在
FixtureDate
列中,您希望显示一周开始的日期。如果是这种情况,那么为什么要使用ROW_NUMBER()?这不是你想要的“将DATEADD(week,week_number-1,@StartFixtureWeek)作为FixtureDate”吗?事实上这是正确的Alex,我没有想到,我认为我需要第行()来做这件事。你可以把它作为一个答案,我会标记它。谢谢,很高兴它起了作用!我已经发布了上述评论作为回答。
1   1   2016-03-01 00:00:00.000
2   2   2016-03-08 00:00:00.000
3   3   2016-03-15 00:00:00.000
4   4   2016-03-22 00:00:00.000
5   5   2016-03-29 00:00:00.000
6   6   2016-04-05 00:00:00.000
7   7   2016-04-12 00:00:00.000
8   8   2016-04-19 00:00:00.000
9   9   2016-04-26 00:00:00.000
10  10  2016-05-03 00:00:00.000
DATEADD(week, week_number - 1, @StartFixtureWeek) AS FixtureDate
...
INSERT INTO dbo.Fixture
-- Join the cte results back to the League_Teams table to convert
-- Indexes used in calculation back to the actual team ids.
SELECT rn,
    week_number,
    DATEADD(week, week_number - 1, @StartFixtureWeek) AS FixtureDate,
    h.id,
    a.id,
    c.leagueid
FROM (
...