SQLize Online / PHPize Online  /  SQLtest Online

A A A
Share      Blog   Popular
Copy Format Clear
/* @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@ IMPORTANT - Each of my courses uses its own subset of the data and tables from this projcet. @@ @@ If you are looking for the practice demo database I use in my courses, follow these links: @@ @@ 1. Query Processing - https://github.com/ami-levin/LinkedIn/tree/master/Query%20Processing/Demo%20Database @@ @@ 2. Window Functions - https://github.com/ami-levin/LinkedIn/tree/master/Window%20Functions/Demo%20Database @@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ */ -- Animal shelter tables and data USE Animal_Shelter; GO -- Variable assignment DECLARE @Shelter_Open DATE = '20160101'; -- Shelter open day DECLARE @Last_Data_Day DATE = '20191231'; -- Last day of data DECLARE @Shelter_State VARCHAR(20) = 'California'; -- Shelter state DECLARE @Shelter_County VARCHAR(20) = 'Los Angeles';-- Shelter county - cities and addresses will be limited to the same county DECLARE @Max_Zip_Code CHAR(5) = '91000'; -- Further limit persons to zip areas below this number DECLARE @Max_Street_Number INT = 1000; -- Maximal number used to generate street address DECLARE @Min_Person_Age INT = 18; -- Minimum age of person as of shelter open DECLARE @Max_Person_Age INT = 70; -- Maximum age of person as of shelter open DECLARE @Num_Persons INT = 120; -- Number of persons DECLARE @Num_Veterinarians INT = 2; -- Number of staff vets DECLARE @Num_Assistants INT = 4; -- Number of staff assistants DECLARE @Num_receptionists INT = 2; -- Number of staff receptionists DECLARE @Num_Managers INT = 1; -- Number of managers DECLARE @Num_Dogs INT = 60; -- Number of dogs in shelter DECLARE @Num_Cats INT = 30; -- Number of cats in shelter DECLARE @Num_Rabbits INT = 10; -- Number of rabbits in shelter DECLARE @Num_Adoptions INT = 70; -- Number of total adoptions DECLARE @Min_Animal_Age_D INT = 1; -- Minimal age in days as of admission DECLARE @Max_Animal_Age_D INT = 18 * 12 * 30; -- Maximal age in days as of admission DECLARE @Min_Adoption_Fee INT = 50; -- Minimal adoption fee DECLARE @Max_Adoption_fee INT = 100; -- Maximal adoption fee DECLARE @Percent_Non_Breed INT = 75; -- Percent of non breed animals BEGIN TRANSACTION; -- easy rollback -- Operational data -- Persons CREATE TABLE Persons ( Email VARCHAR(100) NOT NULL PRIMARY KEY, First_Name VARCHAR(15) NOT NULL, Last_Name VARCHAR(15) NOT NULL, Birth_Date DATE NULL, Address VARCHAR(100) NOT NULL, State VARCHAR(20) NOT NULL, City VARCHAR(30) NOT NULL, Zip_Code CHAR(5) NOT NULL, ); WITH All_Possible_Names AS ( SELECT CASE Genders.Gender WHEN 'M' THEN CPN.Male ELSE CPN.Female END AS First_Name, CPN1.Surname AS Last_Name FROM Reference.Common_Person_Names AS CPN CROSS JOIN Reference.Common_Person_Names AS CPN1 CROSS JOIN (VALUES ('F'), ('M')) AS Genders(Gender) ) INSERT INTO Persons (Email, First_Name, Last_Name, Birth_Date, Address, State, City, Zip_Code) SELECT LOWER(Random_Names.First_Name) + '.' + LOWER(Random_Names.Last_name) + '@' + CASE dbo.Random(1, 6) WHEN 1 THEN 'gmail' WHEN 2 THEN 'gmail' -- Gmail is more popular than other mail providers WHEN 3 THEN 'hotmail' WHEN 4 THEN 'yahoo' WHEN 5 THEN 'outlook' ELSE 'icloud' END + '.com' AS Email, Random_Names.First_Name, Random_Names.Last_Name, CASE WHEN dbo.Random(1,10) > 1 -- 10% did not provide birth date THEN DATEADD(DAY, dbo.Random(0, 365), DATEADD(YEAR, -dbo.Random(@Min_Person_Age, @Max_Person_Age), @Shelter_Open)) ELSE NULL END AS Birth_Date, Addresses.Address, @Shelter_State, Cities.City, Cities.Zip_Code FROM ( SELECT APN.First_Name, APN.Last_Name FROM All_Possible_Names AS APN ORDER BY NEWID() OFFSET 0 ROWS FETCH NEXT @Num_Persons ROWS ONLY ) AS Random_Names CROSS APPLY ( SELECT CZC.City, CZC.Zip_Code FROM Reference.City_Zip_Codes AS CZC INNER JOIN Reference.Cities AS C ON C.State = CZC.State AND C.City = CZC.City WHERE C.State = @Shelter_State AND C.County = @Shelter_County AND (CZC.Zip_Code < @Max_Zip_Code OR @Max_Zip_Code IS NULL) AND Random_Names.First_Name IS NOT NULL -- Force per row execution ORDER BY NEWID() OFFSET 0 ROWS FETCH NEXT 1 ROW ONLY ) AS Cities(City, Zip_Code) CROSS APPLY ( SELECT CAST(dbo.Random(1, @Max_Street_Number) AS VARCHAR(4)) + ' ' + CSN.Street FROM Reference.Common_Street_Names AS CSN WHERE Random_Names.First_Name IS NOT NULL -- Force per row execution ORDER BY NEWID() OFFSET 0 ROWS FETCH NEXT 1 ROW ONLY ) AS Addresses(Address); -- Staff roles CREATE TABLE Staff_Roles ( Role VARCHAR(20) NOT NULL PRIMARY KEY ); INSERT INTO Staff_Roles (Role) VALUES ('Receptionist'), ('Veterinarian'), ('Assistant'), ('Manager'), ('Janitor'); -- Latter will not be assigned, everyone helps clean up -- Staff CREATE TABLE Staff ( Email VARCHAR(100) NOT NULL PRIMARY KEY REFERENCES Persons (Email) ON UPDATE CASCADE ON DELETE NO ACTION, Hire_Date DATE NOT NULL ); INSERT INTO Staff (Email, Hire_Date) SELECT Email, DATEADD(DAY, dbo.Random(0, DATEDIFF(DAY, @Shelter_Open, @Last_Data_Day)), @Shelter_Open) FROM Persons ORDER BY NEWID() OFFSET 0 ROWS FETCH NEXT (@Num_receptionists + @Num_Managers + @Num_Assistants + @Num_Veterinarians) ROWS ONLY; -- Staff use 'animalshelter.com' domain addresses UPDATE Persons SET Email = LEFT(Email, CHARINDEX('@', Email)) + 'animalshelter.com' WHERE Email IN (SELECT Email FROM Staff); -- Staff roles CREATE TABLE Staff_Assignments ( Email VARCHAR(100) NOT NULL REFERENCES Staff (Email) ON UPDATE CASCADE ON DELETE NO ACTION, Role VARCHAR(20) NOT NULL REFERENCES Staff_Roles (Role) ON UPDATE CASCADE ON DELETE NO ACTION, Assigned DATE NOT NULL, PRIMARY KEY (Email, Role), INDEX NCIDX_FK_Staff_Assignments__Roles(Role) ); INSERT INTO Staff_Assignments (Email, Role, Assigned) SELECT S.Email, 'Veterinarian', S.Hire_Date FROM Staff AS S ORDER BY NEWID() OFFSET 0 ROWS FETCH NEXT @Num_Veterinarians ROWS ONLY; INSERT INTO Staff_Assignments (Email, Role, Assigned) SELECT S.Email, 'Assistant', S.Hire_Date FROM Staff AS S WHERE Email NOT IN ( SELECT Email FROM Staff_Assignments ) ORDER BY NEWID() OFFSET 0 ROWS FETCH NEXT (@Num_Assistants) ROWS ONLY; INSERT INTO Staff_Assignments (Email, Role, Assigned) SELECT S.Email, 'Receptionist', S.Hire_Date FROM Staff AS S WHERE Email NOT IN ( SELECT Email FROM Staff_Assignments ) ORDER BY NEWID() OFFSET 0 ROWS FETCH NEXT (@Num_receptionists) ROWS ONLY; INSERT INTO Staff_Assignments (Email, Role, Assigned) SELECT S.Email, 'Manager', S.Hire_Date FROM Staff AS S WHERE Email NOT IN ( SELECT Email FROM Staff_Assignments ) ORDER BY NEWID() OFFSET 0 ROWS FETCH NEXT @Num_Managers ROWS ONLY; -- 1 of each role on day 1 WITH Staff_Rn AS ( SELECT *, ROW_NUMBER() OVER(PARTITION BY role ORDER BY Assigned ASC) AS Rn FROM Staff_Assignments ) UPDATE Staff_Rn SET Staff_Rn.Assigned = @Shelter_Open WHERE Rn = 1; -- update hire dates to match UPDATE Staff SET Hire_Date = (SELECT Assigned FROM Staff_Assignments AS SA WHERE SA.Email = Staff.Email); -- Animals CREATE TABLE Animals ( Name VARCHAR(20) NOT NULL, Species VARCHAR(10) NOT NULL, Primary_Color VARCHAR(10) NOT NULL REFERENCES Reference.Colors (Color), CONSTRAINT PK_Animals PRIMARY KEY (Name, Species), -- Business rule = unique identification of animal as name + species will do for a small sample set -- probably not enough for a real world scenario but depends on shelter naming conventions Implant_Chip_ID UNIQUEIDENTIFIER NOT NULL UNIQUE, -- This is the 'most natural' key, but it's unfamiliar and not very useful for human communication Breed VARCHAR(50) NULL, Gender CHAR(1) NOT NULL CHECK (Gender IN ( 'M', 'F' )), -- no need for gender fluidity in animals :-) Birth_Date DATE NOT NULL, Pattern VARCHAR(20) NOT NULL, CONSTRAINT FK_Animals__Patterns FOREIGN KEY (Species, Pattern) REFERENCES Reference.Patterns (Species, Pattern), Admission_Date DATE NOT NULL, CONSTRAINT FK_Animals__Breeds FOREIGN KEY (Species, Breed) REFERENCES Reference.Breeds (Species, Breed), INDEX NCIDX_FK_Animals__Patterns (Species, Pattern), INDEX NCIDX_FK_Animals__Breeds (Species, Breed), INDEX NCIDX_FK_Animals__Colors (Primary_Color) ); -- Dogs WITH Unpivoted_Names AS ( SELECT CAN.Species, Genders.Gender, CASE WHEN Genders.Gender = 'F' THEN CAN.Female ELSE CAN.Male END AS Name FROM Reference.Common_Animal_Names AS CAN CROSS JOIN (VALUES ('F'), ('M')) AS Genders (Gender) ), DeDuped_F_M_Names -- There are identical names for both M and F of the same species which we want to avoid since gender is not part of key AS ( SELECT UN.Species, CASE WHEN dbo.Random(1, 2) = 1 THEN MAX(Gender) ELSE MIN(Gender) -- Pick arbitraty gender when duplicated END AS Gender, UN.Name FROM Unpivoted_Names AS UN GROUP BY UN.Species, UN.Name ) INSERT INTO Animals (Implant_Chip_ID, Species, Breed, Name, Gender, Birth_Date, Primary_Color, Pattern, Admission_Date) SELECT NEWID() AS Implant_Chip_ID, D.Species, B.Breed, -- Non breeds first D.Name, D.Gender, '20001010' AS Birth_Date, -- Place holder, will update later based on generated admission date C.Color, CP.Pattern, DATEADD(DAY, dbo.Random(0, DATEDIFF(DAY, @Shelter_Open, @Last_Data_Day)), @Shelter_Open) AS Admission_Date FROM DeDuped_F_M_Names AS D CROSS APPLY ( SELECT Color FROM Reference.Colors AS C ORDER BY NEWID(), D.Name OFFSET 0 ROWS FETCH NEXT 1 ROW ONLY ) AS C CROSS APPLY ( SELECT Pattern FROM Reference.Patterns AS P WHERE P.Species = D.Species ORDER BY NEWID(), C.Color OFFSET 0 ROWS FETCH NEXT 1 ROW ONLY ) AS CP CROSS APPLY ( SELECT Breed FROM Reference.Breeds AS B WHERE B.Species = D.Species ORDER BY NEWID(), C.Color OFFSET 0 ROWS FETCH NEXT 1 ROW ONLY ) AS B(Breed) WHERE D.Species = 'Dog' ORDER BY NEWID() OFFSET 0 ROWS FETCH NEXT (@Num_Dogs) ROWS ONLY; -- Cats WITH Unpivoted_Names AS ( SELECT CAN.Species, Genders.Gender, CASE WHEN Genders.Gender = 'F' THEN CAN.Female ELSE CAN.Male END AS Name FROM Reference.Common_Animal_Names AS CAN CROSS JOIN (VALUES ('F'), ('M')) AS Genders (Gender) ), DeDuped_F_M_Names -- There are identical names for both M and F of the same species-avoid since we don't have gender in key AS ( SELECT UN.Species, CASE WHEN dbo.Random(1, 2) = 1 THEN MAX(Gender) ELSE MIN(Gender) -- Pick arbitraty gender when duplicated END AS Gender, UN.Name FROM Unpivoted_Names AS UN GROUP BY UN.Species, UN.Name ) INSERT INTO Animals (Implant_Chip_ID, Species, Breed, Name, Gender, Birth_Date, Primary_Color, Pattern, Admission_Date) SELECT NEWID() AS Implant_Chip_ID, D.Species, B.Breed, -- Non breeds first D.Name, D.Gender, '20001010' AS Birth_Date, -- Place holder, will update later based on generated admission date CASE WHEN B.Breed LIKE '%Blue%' THEN 'Gray' ELSE C.Color END, CP.Pattern, DATEADD(DAY, dbo.Random(0, DATEDIFF(DAY, @Shelter_Open, @Last_Data_Day)), @Shelter_Open) AS Admission_Date FROM DeDuped_F_M_Names AS D CROSS APPLY ( SELECT Color FROM Reference.Colors AS C ORDER BY NEWID(), D.Name OFFSET 0 ROWS FETCH NEXT 1 ROW ONLY ) AS C CROSS APPLY ( SELECT Pattern FROM Reference.Patterns AS P WHERE P.Species = D.Species ORDER BY NEWID(), C.Color, D.Name OFFSET 0 ROWS FETCH NEXT 1 ROW ONLY ) AS CP CROSS APPLY ( SELECT Breed FROM Reference.Breeds AS B WHERE B.Species = D.Species ORDER BY NEWID(), C.Color, D.Name, CP.Pattern OFFSET 0 ROWS FETCH NEXT 1 ROW ONLY ) AS B(Breed) WHERE D.Species = 'Cat' ORDER BY NEWID() OFFSET 0 ROWS FETCH NEXT (@Num_Cats) ROWS ONLY; -- Rabbits WITH Unpivoted_Names AS ( SELECT CAN.Species, Genders.Gender, CASE WHEN Genders.Gender = 'F' THEN CAN.Female ELSE CAN.Male END AS Name FROM Reference.Common_Animal_Names AS CAN CROSS JOIN (VALUES ('F'), ('M')) AS Genders (Gender) ), DeDuped_F_M_Names -- There are identical names for both M and F of the same species-avoid since we don't have gender in key AS ( SELECT UN.Species, CASE WHEN dbo.Random(1, 2) = 1 THEN MAX(Gender) ELSE MIN(Gender) -- Pick arbitraty gender when duplicated END AS Gender, UN.Name FROM Unpivoted_Names AS UN GROUP BY UN.Species, UN.Name ) INSERT INTO Animals (Implant_Chip_ID, Species, Breed, Name, Gender, Birth_Date, Primary_Color, Pattern, Admission_Date) SELECT NEWID() AS Implant_Chip_ID, D.Species, B.Breed, -- Non breeds first D.Name, D.Gender, '20001010' AS Birth_Date, -- Place holder, will update later based on generated admission date C.Color, CP.Pattern, DATEADD(DAY, dbo.Random(0, DATEDIFF(DAY, @Shelter_Open, @Last_Data_Day)), @Shelter_Open) AS Admission_Date FROM DeDuped_F_M_Names AS D CROSS APPLY ( SELECT Color FROM Reference.Colors AS C ORDER BY NEWID(), D.Name OFFSET 0 ROWS FETCH NEXT 1 ROW ONLY ) AS C CROSS APPLY ( SELECT Pattern FROM Reference.Patterns AS P WHERE P.Species = D.Species ORDER BY NEWID(), C.Color OFFSET 0 ROWS FETCH NEXT 1 ROW ONLY ) AS CP CROSS APPLY ( SELECT Breed FROM Reference.Breeds AS B WHERE B.Species = D.Species ORDER BY NEWID(), C.Color OFFSET 0 ROWS FETCH NEXT 1 ROW ONLY ) AS B(Breed) WHERE D.Species = 'Rabbit' ORDER BY NEWID() OFFSET 0 ROWS FETCH NEXT (@Num_Rabbits) ROWS ONLY; -- Most animals are non breed UPDATE Animals SET Breed = CASE WHEN dbo.Random(1, 100) > @Percent_Non_Breed THEN Breed ELSE NULL END; -- Now update to 'real' birth dates based on generated admission date UPDATE Animals SET Birth_Date = DATEADD(DAY, -dbo.Random(@Min_Animal_Age_D, @Max_Animal_Age_D), Admission_Date); -- Adoptions CREATE TABLE Adoptions ( Name VARCHAR(20) NOT NULL, Species VARCHAR(10) NOT NULL, CONSTRAINT FK_Adoptions__Animals FOREIGN KEY (Name, Species) REFERENCES Animals (Name, Species) ON UPDATE CASCADE ON DELETE NO ACTION, Adopter_Email VARCHAR(100) NOT NULL REFERENCES Persons (Email) ON UPDATE CASCADE ON DELETE NO ACTION, PRIMARY KEY (Name, Species, Adopter_Email), -- An animal may be adopted only once by the same person (allows for future implementation of adoption returns) Adoption_Date DATE NOT NULL, Adoption_Fee SMALLINT NOT NULL CHECK (Adoption_Fee >= 0), INDEX NCIDX_FK_Adoptions__Persons (Adopter_Email), ); INSERT INTO Adoptions (Name, Species, Adopter_Email, Adoption_Date, Adoption_Fee) SELECT A.Name, A.Species, Adopter.Email, Adoption.Date, dbo.Random(@Min_Adoption_Fee, @Max_Adoption_fee) FROM Animals AS A CROSS APPLY ( SELECT C.Date FROM Reference.Calendar AS C WHERE C.Date > A.Admission_Date AND C.Date < @Last_Data_Day ORDER BY NEWID() OFFSET 0 ROWS FETCH NEXT 1 ROW ONLY ) AS Adoption(Date) CROSS APPLY ( SELECT Email FROM Persons WHERE Adoption.Date IS NOT NULL -- dummy reference to force row execution ORDER BY NEWID() OFFSET 0 ROWS FETCH NEXT 1 ROW ONLY ) AS Adopter ORDER BY NEWID() OFFSET 0 ROWS FETCH NEXT @Num_Adoptions ROWS ONLY; /* -- Future optional -- Animal routine checkups CREATE TABLE Routine_Checkups ( Name VARCHAR(20) NOT NULL, Species VARCHAR(10) NOT NULL, CONSTRAINT FK_Routine_Checkups__Animals FOREIGN KEY (Name, Species) REFERENCES Animals (Name, Species), Checkup_Time DATETIME2 NOT NULL, Temperature_F DECIMAL(4, 1) NOT NULL, Heart_Rate TINYINT NOT NULL, Respiration TINYINT NOT NULL, Weight_Lbs DECIMAL(4, 1) NOT NULL, Comments VARCHAR(500) NULL, Performed_By VARCHAR(100) NOT NULL REFERENCES Staff (Email) ON UPDATE CASCADE ON DELETE NO ACTION, PRIMARY KEY (Name, Species, Checkup_Time), INDEX NCIDX_FK_Routine_Checkups__Staff(Performed_By) ); INSERT INTO Routine_Checkups (Name, Species, Checkup_Time, Temperature_F, Heart_Rate, Respiration, Weight_Lbs, Comments, Performed_By) SELECT A.Name, A.Species, DATEADD(MINUTE, (7 * 60) + dbo.Random(0, (8 * 60)), CAST(C.Date AS DATETIME2)) AS Checkup_Time, ROUND( (SNR.Temperature_Low + ((SNR.Temperature_High - SNR.Temperature_Low) / 2.00)) -- Middle of range + ((dbo.Random(-10, 10) / 30.00) * (SNR.Temperature_High - SNR.Temperature_Low)) -- +/- 30% around the middle of the range + CASE WHEN dbo.Random(1, 100) < 100 -- 1 in 100 rows give abnormal reading THEN 0 ELSE (dbo.Random(-10, 10) / 30.00) * (SNR.Temperature_High - SNR.Temperature_Low) -- by +/- 1/3 of range END, 1 ) AS Temperature, ROUND( (SNR.Heart_Rate_Low + ((SNR.Heart_Rate_high - SNR.Heart_Rate_Low) / 2.00)) -- Middle of range + ((dbo.Random(-10, 10) / 30.00) * (SNR.Heart_Rate_high - SNR.Heart_Rate_Low)) -- +/- 30% around the middle of the range + CASE WHEN dbo.Random(1, 100) < 100 -- 1 in 100 rows give abnormal reading THEN 0 ELSE (dbo.Random(-10, 10) / 30.00) * (SNR.Heart_Rate_high - SNR.Heart_Rate_Low) -- by +/- 1/3 of range END, 0 ) AS Heart_Rate, ROUND( (SNR.Respiratory_Rate_Low + ((SNR.Respiratory_Rate_High - SNR.Respiratory_Rate_Low) / 2.00)) -- Middle of range + ((dbo.Random(-10, 10) / 30.00) * (SNR.Respiratory_Rate_High - SNR.Respiratory_Rate_Low)) -- +/- 30% around the middle of the range + CASE WHEN dbo.Random(1, 100) < 100 -- 1 in 100 rows give abnormal reading THEN 0 ELSE (dbo.Random(-10, 10) / 30.00) * (SNR.Respiratory_Rate_High - SNR.Respiratory_Rate_Low) -- by +/- 1/3 of range END, 0 ) AS Respistory_Rate, ROUND( CASE A.Species WHEN 'Cat' THEN 6.00 + ((ABS(CHECKSUM(A.Breed)) % 24) / 2) -- consistent base weight / breed + ((CASE WHEN dbo.Random(1, 10) < 10 THEN 0 ELSE 1 END) * (dbo.Random(-10, 10) / 20.00)) -- cats (6 - 17 lbs) +/- 0.5 lbs 1 in 10 WHEN 'Dog' THEN 15.00 + ((ABS(CHECKSUM(A.Breed)) % 72) / 2) + ((CASE WHEN dbo.Random(1, 10) < 10 THEN 0 ELSE 1 END) * (dbo.Random(-15, 15) / 10.00)) -- dogs (15 - 50 lbs) + / 1.5 lbs 1 in 10 ELSE 2.00 + (ABS(CHECKSUM(A.Breed) % 21)) / 3 + ((CASE WHEN dbo.Random(1, 20) < 20 THEN 0 ELSE 1 END) * (dbo.Random(-10, 10) / 50.00)) -- rabbits (2 - 8 lbs) +/ 0.2 lbs 1 in 20 END, 1 ) AS Weight, NULL AS Comments, Staff.Email FROM ( Animals AS A LEFT OUTER JOIN Adoptions AS AD ON A.Name = AD.Name AND A.Species = AD.Species ) INNER JOIN Reference.Species_Vital_Signs_Ranges AS SNR ON A.Species = SNR.Species CROSS JOIN Reference.Calendar AS C CROSS APPLY ( SELECT Email FROM Staff WHERE C.Date >= Staff.Hire_Date AND Email IN (SELECT Email FROM Staff_Assignments WHERE Role IN ('Veterinarian', 'Assistant')) -- Dirty shortcut but Emails are unique... ORDER BY NEWID() OFFSET 0 ROWS FETCH NEXT 1 ROW ONLY ) AS Staff WHERE C.Date BETWEEN @Shelter_Open AND @Last_Data_Day AND C.Weekday BETWEEN 2 AND 6 AND C.US_Federal_Holiday IS NULL AND (ABS(CHECKSUM(A.Name + A.Species)) % 5) + 2 = C.Weekday -- every animal checked weekly AND C.Date >= A.Admission_Date -- only post admission AND C.Date <= ISNULL(AD.Adoption_Date, @Last_Data_Day) -- only pre-adoption AND ABS(CHECKSUM(A.Name + A.Species + CAST(C.Date AS VARCHAR(20))) % 100) > 74; -- only 1/4 of all possible combinations */ CREATE TABLE Vaccinations ( Name VARCHAR(20) NOT NULL, Species VARCHAR(10) NOT NULL, CONSTRAINT FK_Vaccinations__Animals FOREIGN KEY (Name, Species) REFERENCES Animals (Name, Species), Vaccination_Time DATETIME2 NOT NULL, Vaccine VARCHAR(50) NOT NULL, CONSTRAINT FK_Vaccinations__Species_Vaccines FOREIGN KEY (Species, Vaccine) REFERENCES Reference.Species_Vaccines (Species, Vaccine) ON UPDATE CASCADE ON DELETE NO ACTION, Batch VARCHAR(20) NOT NULL, Comments VARCHAR(500) NULL, Email VARCHAR(100) NOT NULL REFERENCES Staff (Email) ON UPDATE CASCADE ON DELETE NO ACTION, PRIMARY KEY (Name, Species, Vaccine, Vaccination_Time), INDEX NCIDX_FK_Vaccinations__Vaccines(Species, Vaccine), INDEX NCIDX_FK_Vaccinations__Staff(Email) ); INSERT INTO Vaccinations (Name, Species, Vaccination_Time, Vaccine, Batch, Comments, Email) SELECT A.Name, A.Species, DATEADD(MINUTE, (7 * 60) + dbo.Random(0, (8 * 60)), CAST(C.Date AS DATETIME2)) AS Vaccination_Time, V.Vaccine, CHAR(dbo.Random(ASCII('A'), ASCII('Z'))) + '-' + CAST(dbo.Random(500000000, 99000000) AS CHAR(9)), NULL, Staff.Email FROM ( Animals AS A LEFT OUTER JOIN Adoptions AS AD ON A.Name = AD.Name AND A.Species = AD.Species ) INNER JOIN Reference.Species_Vaccines AS V ON V.Species = A.Species CROSS JOIN Reference.Calendar AS C CROSS APPLY ( SELECT Email FROM Staff WHERE C.Date >= Staff.Hire_Date -- After hire date AND A.name IS NOT NULL AND V.Vaccine IS NOT NULL AND Email IN (SELECT Email FROM Staff_Assignments WHERE Role IN ('Veterinarian', 'Assistant')) -- Dirty shortcut but Emails are unique... ORDER BY NEWID() OFFSET 0 ROWS FETCH NEXT 1 ROW ONLY ) AS Staff WHERE V.Species = A.Species AND C.Date BETWEEN @Shelter_Open AND @Last_Data_Day AND (ABS(CHECKSUM(A.Species + A.Name)) % 365) + 1 = C.Day_of_Year -- every animal vaccinated annualy AND C.Weekday BETWEEN 2 AND 6 -- on weekdays only AND C.US_Federal_Holiday IS NULL -- not on holidays AND C.Date >= A.Admission_Date -- only post admission AND C.Date <= ISNULL(AD.Adoption_Date, @Last_Data_Day) -- only pre-adoption AND 1 = CASE WHEN DATEDIFF(WEEK, A.Birth_Date, C.Date) NOT BETWEEN 14 AND 16 -- Parvo between 14 and 16 weeks only AND V.Vaccine = 'Parvovirus' THEN 0 ELSE 1 END AND ABS(CHECKSUM(A.Name + V.Vaccine + CAST(C.Date AS VARCHAR(20))) % 100) > 66 -- only 1/3 of all possible combinations ----------------------- -- Sanity check data -- ----------------------- SELECT 'Persons' AS Table_Name, * FROM Persons ORDER BY Email OFFSET 0 ROWS FETCH NEXT 100 ROWS ONLY; SELECT 'Staff' AS Table_Name, * FROM Staff ORDER BY Email OFFSET 0 ROWS FETCH NEXT 100 ROWS ONLY; SELECT 'Staff_Assignments' AS Table_Name, * FROM Staff_Assignments ORDER BY Email OFFSET 0 ROWS FETCH NEXT 100 ROWS ONLY; SELECT 'Animals' AS Table_Name, * FROM Animals ORDER BY Species, Breed, Name OFFSET 0 ROWS FETCH NEXT 100 ROWS ONLY; SELECT 'Adoptions' AS Table_Name, * FROM Adoptions ORDER BY Adoption_Date OFFSET 0 ROWS FETCH NEXT 100 ROWS ONLY; --SELECT 'Routine_Checkups' AS Table_Name, -- * --FROM Routine_Checkups --ORDER BY Checkup_Time OFFSET 0 ROWS FETCH NEXT 100 ROWS ONLY; SELECT 'Vaccinations' AS Table_Name, * FROM Vaccinations ORDER BY Vaccination_Time OFFSET 0 ROWS FETCH NEXT 100 ROWS ONLY; SELECT COUNT(*) AS Num_Persons, MIN(Birth_Date) AS Min_Birth_Date, MAX(Birth_Date) AS Max_Birth_Date FROM Persons; SELECT COUNT(*) AS Num_Staff, MIN(Hire_Date) AS Min_Hire_Date, MAX(Hire_Date) AS Max_Hire_Date FROM Staff; SELECT COUNT(*) AS Num_Assignments, MIN(Assigned) AS Min_A, MAX(Assigned) AS Max_A FROM Staff_Assignments; SELECT Species, Breed, COUNT(*) AS Num_Animals FROM Animals GROUP BY GROUPING SETS (Species), (Breed) ORDER BY Species, Breed, Num_Animals DESC; --SELECT COUNT(*) AS Total_Routine_Checkups --FROM Routine_Checkups; SELECT COUNT(*) AS Total_Vaccinations FROM Vaccinations AS V SELECT COUNT(*) AS Num_Adoptions, MIN(Adoption_Date) AS Min_Adoption_Date, MAX(Adoption_Date) AS Max_Adoption_Date FROM Adoptions; SELECT Adopter_Email, COUNT(*) AS Num_Adopted FROM Adoptions GROUP BY Adopter_Email; --SELECT A.Species, -- COUNT(*) AS Num_Rows, -- MIN(RC.Temperature_F) AS Min_Temp, -- MAX(RC.Temperature_F) AS Max_Temp, -- AVG(RC.Temperature_F) AS Avg_Temp, -- MIN(RC.Heart_Rate) AS Min_Heart, -- MAX(RC.Heart_Rate) AS Max_Heart, -- AVG(RC.Heart_Rate) AS Avg_Heart, -- MIN(RC.Respiration) AS Min_Resp, -- MAX(RC.Respiration) AS Max_Resp, -- AVG(RC.Respiration) AS Avg_Resp, -- MIN(RC.Weight_Lbs) AS Min_Weight, -- MAX(RC.Weight_Lbs) AS Max_Weight, -- AVG(RC.Weight_Lbs) AS Avg_Weight --FROM Routine_Checkups AS RC -- INNER JOIN -- Animals AS A -- ON A.Name = RC.Name -- AND -- A.Species = RC.Species --GROUP BY A.Species; COMMIT TRANSACTION;
Stuck with a problem? Got Error? Ask ChatGPT!
Copy Clear