sql >> データベース >  >> RDS >> Sqlserver

特定の数学アルゴリズムをコーディングする方法

    別の Oracle ソリューション。

    セットアップ :

    CREATE TABLE League (
      LeagueID   INT PRIMARY KEY, 
      LeagueName VARCHAR(30) UNIQUE
    );
    
    CREATE TABLE Team (
      TeamID           INT PRIMARY KEY, 
      TeamAbbreviation CHAR(3) UNIQUE, 
      TeamName         VARCHAR(50) UNIQUE, 
      LeagueID         INT CONSTRAINT FK_Team_League REFERENCES League(LeagueID) 
    );
    
    CREATE TABLE Fixture (
      FixtureID   INT PRIMARY KEY,
      WeekNumber  INT NOT NULL,
      FixtureDate DATE NULL,
      HomeTeamID  INT NULL,
      AwayTeamID  INT NULL,
      LeagueID    INT CONSTRAINT FK_Fixture_League REFERENCES League(LeagueID)
    );
    
    INSERT INTO League VALUES ( 1, 'League 1' );
    INSERT INTO League VALUES ( 2, 'League 2' );
    
    INSERT INTO Team VALUES ( 1, 'AAA', 'Team A', 1 );
    INSERT INTO Team VALUES ( 2, 'BBB', 'Team B', 1 );
    INSERT INTO Team VALUES ( 3, 'CCC', 'Team C', 1 );
    INSERT INTO Team VALUES ( 4, 'DDD', 'Team D', 1 );
    INSERT INTO Team VALUES ( 5, 'EEE', 'Team E', 2 );
    INSERT INTO Team VALUES ( 6, 'FFF', 'Team F', 2 );
    INSERT INTO Team VALUES ( 7, 'GGG', 'Team G', 2 );
    INSERT INTO Team VALUES ( 8, 'HHH', 'Team H', 2 );
    INSERT INTO Team VALUES ( 9, 'III', 'Team I', 2 );
    

    挿入 - 備品 :

    INSERT INTO Fixture
    WITH league_teams ( id, leagueid, idx, is_fake, num_teams, num_fake ) 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
      -- and if this is an odd number then generate a fake team as well.
      SELECT TeamID,
             LeagueID,
             ROW_NUMBER() OVER ( PARTITION BY LeagueID ORDER BY TeamID ) - 1,
             0,
             COUNT(1) OVER ( PARTITION BY LeagueID ),
             MOD( COUNT(1) OVER ( PARTITION BY LeagueID ), 2 )
      FROM Team
      UNION ALL
      SELECT NULL,
             LeagueID,
             COUNT(1),
             1,
             COUNT(1),
             1
      FROM   Team
      GROUP BY LeagueID
      HAVING MOD( COUNT(1), 2 ) > 0
    ),
    cte ( home_idx, away_idx, week_number, leagueID, num_teams, num_fake ) AS (
      -- Start by calculating the round 1 games
      SELECT idx,
             num_teams + num_fake - 1 - idx,
             1,
             LeagueID,
             num_teams,
             num_fake
      FROM   league_teams
      WHERE  2 * idx < num_teams
    UNION ALL
      -- Then generate the 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 MOD( home_idx + 1, num_teams + num_fake -1 )
               END,
             CASE away_idx
               WHEN num_teams + num_fake - 1
               THEN away_idx
               ELSE MOD( 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
    )
    -- Finally join the cte results back to the League_Teams table to convert
    -- the indexes used in calculation back to the actual team ids.
    SELECT rn,
           week_number,
           NULL,
           h.id,
           a.id,
           c.leagueid
    FROM   (
             -- This step isn't necessary but it keeps the results in a nice order.
             SELECT ROWNUM 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 fixture;
    
     FIXTUREID WEEKNUMBER FIXTUREDATE         HOMETEAMID AWAYTEAMID   LEAGUEID
    ---------- ---------- ------------------- ---------- ---------- ----------
             1          1                              1          4          1 
             2          1                              2          3          1 
             3          1                              5                     2 
             4          1                              6          9          2 
             5          1                              7          8          2 
             6          2                              2          4          1 
             7          2                              3          1          1 
             8          2                              6                     2 
             9          2                              7          5          2 
            10          2                              8          9          2 
            11          3                              3          4          1 
            12          3                              1          2          1 
            13          3                              7                     2 
            14          3                              8          6          2 
            15          3                              9          5          2 
            16          4                              8                     2 
            17          4                              9          7          2 
            18          4                              5          6          2 
            19          5                              9                     2 
            20          5                              5          8          2 
            21          5                              6          7          2 
            22          4                              4          1          1 
            23          4                              3          2          1 
            24          6                                         5          2 
            25          6                              9          6          2 
            26          6                              8          7          2 
            27          5                              4          2          1 
            28          5                              1          3          1 
            29          7                                         6          2 
            30          7                              5          7          2 
            31          7                              9          8          2 
            32          6                              4          3          1 
            33          6                              2          1          1 
            34          8                                         7          2 
            35          8                              6          8          2 
            36          8                              5          9          2 
            37          9                                         8          2 
            38          9                              7          9          2 
            39          9                              6          5          2 
            40         10                                         9          2 
            41         10                              8          5          2 
            42         10                              7          6          2 
    

    (注:FixtureDate NULL です これをどのように生成したいかは不明ですが、週番号を取得し、これをシーズンの開始からのオフセットとして使用して日付を生成できるはずです)



    1. SQL ServerでFILEPROPERTY()を使用する方法

    2. トランザクションレプリケーションを作成する方法

    3. Oracle FormsのDLL(c#)から関数を呼び出す

    4. 7つのSQLServerソートの内部–パート1