===== Grand National Sweepstake (PostgreSQL) =====
==== Create Database ====
CREATE DATABASE GrandNational;
==== Create tables and insert data ====
-- Lists the entrants in the sweepstake
Drop table participants;
Create table if not exists participants (ID serial,
Name varchar(20) PRIMARY KEY NOT NULL CHECK (length(Name) > 0));
insert into participants (name) values ('Ian');
insert into participants (name) values ('Pat');
insert into participants (name) values ('Graham');
insert into participants (name) values ('Tracy');
insert into participants (name) values ('Michaela');
insert into participants (name) values ('Glenn');
-- List of horses entered into the Grand National
Drop table horses;
Create table if not exists horses (HorseNo smallint PRIMARY KEY NOT NULL CHECK (HorseNo between 1 and 40),
Name varchar(40) UNIQUE);
insert into horses values (1,'Bristol De Mai');
insert into horses values (2,'Chris Dream');
insert into horses values (3,'Yala Enki');
insert into horses values (4,'Ballyoptic');
insert into horses values (5,'Definitly Red');
insert into horses values (6,'Lake View Lad');
insert into horses values (7,'Burrows Saint');
insert into horses values (8,'Magic Of Light');
insert into horses values (9,'Acapella Bourgeois');
insert into horses values (10,'Talkischeap');
insert into horses values (11,'Tout Est Permis');
insert into horses values (12,'Anibale Fly');
insert into horses values (13,'Mister Malarky');
insert into horses values (14,'Kimberlite Candy');
insert into horses values (15,'Any Second Now');
insert into horses values (16,'Balko Des Flos');
insert into horses values (17,'Alpha Des Obeaux');
insert into horses values (18,'OK Corral');
insert into horses values (19,'Takingrisks');
insert into horses values (20,'Shattered Love');
insert into horses values (21,'Jett');
insert into horses values (22,'Lord Du Mesnil');
insert into horses values (23,'Potters Corner');
insert into horses values (24,'Class Conti');
insert into horses values (25,'Milan Native');
insert into horses values (26,'Discorama');
insert into horses values (27,'Vieux Lion Rouge');
insert into horses values (28,'Cloth Cap');
insert into horses values (29,'Caberet Queen');
insert into horses values (30,'Minellacelebration');
insert into horses values (31,'Canelo');
insert into horses values (32,'The Long Mile');
insert into horses values (33,'Give Me A Copper');
insert into horses values (34,'Farclas');
insert into horses values (35,'Minella Times');
insert into horses values (36,'Sub Lieutenant');
insert into horses values (37,'Hogans Height');
insert into horses values (38,'Double Shuffle');
insert into horses values (39,'Ami Desbois');
insert into horses values (40,'Blaklion');
-- Lists the entrants and the horses that they got
drop table sweepstake;
create table if not exists sweepstake (PlayerID smallint,
HorseNo smallint PRIMARY KEY NOT NULL CHECK (HorseNo between 1 and 40),
HorseName varchar(40) UNIQUE);
==== Create procedures ====
-- Initialise the SWEEPSTAKE table
-- PostgreSQL Version 11 and Above
create or replace procedure init()
LANGUAGE SQL
as $$
delete from sweepstake;
insert into sweepstake (HorseNo, HorseName) (select horseno, name from horses);
$$;
-- PostgreSQL Version 10 and Below
create or replace function init()
RETURNS void AS $$
BEGIN
delete from sweepstake;
insert into sweepstake (HorseNo, HorseName) (select horseno, name from horses);
END;
$$ LANGUAGE plpgsql;
-- Performs one round of the draw.
create or replace function OneCycle()
RETURNS void AS $$
DECLARE
C1 CURSOR FOR select PlayerID, PlayerName, horseno, HorseName from (
select row_number() over (order by random() ASC) row_num,
HorseNo, HorseName from sweepstake where playerid is null) as T1,
(select id PlayerID, name PlayerName from participants) as T2
where row_num = PlayerID;
BEGIN
FOR a IN C1
LOOP
Update sweepstake set PlayerID = a.PlayerID where HorseNo = a.HorseNo;
END LOOP;
END;
$$ LANGUAGE plpgsql;
-- Generate the sweepstake data
create or replace function GenSweepstake()
RETURNS void AS $$
DECLARE
C1 CURSOR FOR select name, horseno, horsename
from participants, sweepstake
where id = playerid order by horseno;
NoParticipants real;
NoHorses real;
NoCycles smallint;
BEGIN
select count(*) into NoParticipants from participants;
select count(*) into NoHorses from horses;
NoCycles := ceil(NoHorses/NoParticipants);
perform init();
FOR a IN 1..NoCycles
LOOP
perform OneCycle();
END LOOP;
END;
$$ LANGUAGE plpgsql;
==== Create Views ====
create or replace view v_sweepstake as
select name, horseno, horsename
from participants, sweepstake
where id = playerid
order by horseno;
create or replace view v_check as
select name, count(name) No_Horses from v_sweepstake
group by name
order by 2 DESC;
==== Generate Sweepstake ====
SELECT GenSweepstake;