Sqlserver
 sql >> Teknologi Basis Data >  >> RDS >> Sqlserver

Cara membuat kode algoritma matematika tertentu

Solusi Oracle lainnya.

Penyiapan :

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 );

Sisipkan - Jadwal :

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;

Keluaran :

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 

(Catatan:FixtureDate adalah NULL karena tidak jelas bagaimana Anda ingin ini dihasilkan tetapi Anda harus dapat mengambil nomor minggu dan menggunakan ini sebagai offset dari awal musim untuk menghasilkan tanggal)



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. kapan kolom yang dihitung akan diperbarui?

  2. Kinerja SQL Server untuk tabel ubah, ubah kolom, ubah tipe data

  3. Pengikatan Skema dengan Fungsi Kolom Terhitung

  4. Kapan saya harus menggunakan CROSS APPLY daripada INNER JOIN?

  5. Apakah mungkin menggunakan parameter kueri untuk mengisi kata kunci IN