season based database schema/design - sql-server

I have a simple schema for a sports registration system till the concept of a season is introduced:
A player registers as part of a Team
A Team registers as part of a Club
A team plays in a Division
An Organization creates Divisions
This happens every season. So I need a way to keep track of all of this every season. What would be the best approach here? Should I introduce a "Season" entity and make many-to-many relationships between all the entities above as applicable? Or is there a way to just "Archive" everything every season but also be able to pull all the season based data up on the fly (for reporting and what not)?

This design allows teams to move to a different division from season to season, while not having to be re-created every year (though it doesn't allow for things like the Winnipeg Jets moving to Phoenix and keeping their old name with their historical season stats).
CREATE TABLE dbo.Organizations
(
OrgID INT PRIMARY KEY,
Name NVARCHAR(255) NOT NULL UNIQUE
-- , ... other columns
);
CREATE TABLE dbo.Divisions
(
DivisionID INT PRIMARY KEY,
Name NVARCHAR(255) NOT NULL,
OrgID INT NOT NULL FOREIGN KEY REFERENCES dbo.Organizations(OrgID)
-- , ... other columns
-- UNIQUE might be (Name) or (OrgID, Name)
);
CREATE TABLE dbo.Clubs
(
ClubID INT PRIMARY KEY,
Name NVARCHAR(255) NOT NULL UNIQUE,
-- , ... other columns
);
CREATE TABLE dbo.Teams
(
TeamID INT PRIMARY KEY,
Name NVARCHAR(255) NOT NULL,
ClubID INT NOT NULL FOREIGN KEY REFERENCES dbo.Clubs(ClubID)
-- , ... other columns
);
Now to keep track of seasons:
CREATE TABLE dbo.Seasons
(
SeasonID INT PRIMARY KEY,
StartDate DATE NOT NULL,
EndDate DATE,
Name NVARCHAR(255) NOT NULL -- e.g. '1997-98' for seasons that cross Jan 1
-- , ... other columns
);
CREATE TABLE dbo.SeasonTeams
(
SeasonID INT FOREIGN KEY REFERENCES dbo.Seasons(SeasonID),
DivisionID INT FOREIGN KEY REFERENCES dbo.Divisions(DivisionID),
TeamID INT FOREIGN KEY REFERENCES dbo.Teams(TeamID),
PRIMARY KEY (SeasonID, DivisionID, TeamID)
);
You probably want constraints or triggers to prevent a team from belonging to more than one division in any given year.
Now you'll also want to denote a roster for a given season / team.
CREATE TABLE dbo.Players
(
PlayerID INT PRIMARY KEY,
Name NVARCHAR(255) NOT NULL,
-- , ... other columns
);
CREATE TABLE dbo.TeamRoster
(
PlayerID INT NOT NULL FOREIGN KEY REFERENCES dbo.Players(PlayerID),
TeamID INT NOT NULL,
SeasonID INT NOT NULL,
DivisionID INT NOT NULL,
FOREIGN KEY (TeamID, SeasonID, DivisionID) REFERENCES
dbo.SeasonTeams (TeamID, SeasonID, DivisionID)
);
You'll also want tables for schedules, standings, player stats etc... but that should be a start.

Related

Correct way to create a foreign key based on type, in SQL Server and Entity Framework Core

I use Entity Framework Core and SQL Server in my application. I am very familiar with foreign keys but I would like to learn the correct way to give a foreign key to an entity which is based on a type.
For example:
Parent class AppUser:
CREATE TABLE AppUser
(
Id INT NOT NULL PRIMARY KEY IDENTITY(1, 1),
Name VARCHAR(255) NOT NULL,
UserTypeId SMALLINT NOT NULL -- !This is the important part for me! if 0 = Student if 1 = Teacher
);
CREATE TABLE Student
(
Id INT NOT NULL PRIMARY KEY IDENTITY(1, 1),
AppUserId INT NOT NULL,
CONSTRAINT FK_Student_AppUser FOREIGN KEY (AppUserId)
REFERENCES AppUser(Id)
);
CREATE TABLE Teacher
(
Id INT NOT NULL PRIMARY KEY IDENTITY(1, 1),
AppUserId INT NOT NULL,
CONSTRAINT FK_Student_AppUser FOREIGN KEY (AppUserId)
REFERENCES AppUser(Id)
);
My question: is there a better way to have this relationship. Because in Entity Framework, when I try to get a user, I always need to check for the TypeId and have an if else block for the type, then make the query on the table student or teacher. Any advice would be great. Thanks!
According to your table structures, if you want to get student through AppUser Id, you can directly use this code :
var data = _context.Student.Include(x => x.AppUser).Where(x => x.AppUserId == userId).FirstOrDefault();
Next, you only need to distinguish the parameter of data .
If data is null, it represents that the Id of AppUser is not a student but a teacher(which means the UserTypeId field value is 1), otherwise, you can update the student fields you want.
if (data != null)
{
//update student
}

i need Database table creating

i created my tables and I'm stuck at the last one,
here is the tables that been created correctly
CREATE TABLE Staff (
Staff_ID INT NOT NULL PRIMARY KEY,
First_Name VARCHAR(50),
Last_Name VARCHAR(50),
Username VARCHAR(10),
Password VARCHAR(10),
Address VARCHAR(30)
)
CREATE TABLE Category (
Category_ID INT NOT NULL PRIMARY KEY,
Name VARCHAR(30)
)
CREATE TABLE Author (
Author_ID INT NOT NULL PRIMARY KEY,
First_Name VARCHAR(50),
Last_Name VARCHAR(50),
Birth_Place VARCHAR(30),
Birth_Date DATE
)
CREATE TABLE Publisher (
Publisher_ID INT NOT NULL PRIMARY KEY,
Name VARCHAR(50)
)
and this is the one I'm getting an error :
CREATE TABLE Book (
Book_ID INT NOT NULL PRIMARY KEY,
Title VARCHAR(50),
Edition INT(30),
Year_Published INT(4),
FOREIGN KEY (Publisher_ID) REFERENCES Publisher(Publisher_ID),
FOREIGN KEY (Author_ID) REFERENCES Author(Author_ID),
FOREIGN KEY (Category_ID) REFERENCES Category(Category_ID)
)
the error says:
"ORA-00907: missing right parenthesis"
INT can not have a scale associated with it so YEAR_PUBLISHED and EDITION are incorrect definitions.
I believe that, generally, you would be better off sticking to NUMBER for numeric datatypes, eg NUMBER(4), NUMBER(30).
In the database the INT datatype is simply a sub-type of NUMBER so you aren't gaining anything by using it:
type NUMBER is NUMBER_BASE;
subtype INTEGER is NUMBER(38,0);
subtype INT is INTEGER;
If you want to see the definitions for the various 'other' numeric datatypes take a look at the SYS.STANDARD package.
The INT data type does not have a precision.
You also need to define the Publisher_ID, Author_ID and Category_ID columns.
It is good practice to name your constraints.
A PRIMARY KEY column is both NOT NULL and UNIQUE so you do not need to include a second NOT NULL constraint.
Like this:
CREATE TABLE Book (
Book_ID INT CONSTRAINT Book__Book_id__PK PRIMARY KEY,
Title VARCHAR(50),
Edition INT,
Year_Published INT,
Publisher_ID INT CONSTRAINT Book__Publisher_ID__FK REFERENCES Publisher(Publisher_ID),
Author_ID INT CONSTRAINT Book__Author_id__FK REFERENCES Author(Author_ID),
Category_ID INT CONSTRAINT Book__category_ID__FK REFERENCES Category(Category_ID)
);

Using the last inserted record's ID as a foreign key

I am making a database which links together two tables via the primary key of the first table. The one with the primary key which links the two is created first but how do i make the second record get the ID of the record I just created?
create table Person
(
Person_ID int IDENTITY(100000,1) primary key,
First_Name varchar(20) not null,
Last_Name varchar(20) not null,
)
create table Employee
(
Employee_ID int identity(100000,1) primary key,
Person_ID int references Person(Person_ID),
Employee_Type varchar(10)
)
insert into Person(First_Name, Last_Name) values ('Michael', 'Chu');
insert into Employee(Person_ID, Employee_Type,) values (????????, 'Admin');
I've had a look at the 'last()' function but not really sure how to utilise that. Other then that, I have no idea. Can someone help me out or guide me in the right direction.
try this:
create table Person
(
Person_ID int IDENTITY(100000,1) primary key,
First_Name varchar(20) not null,
Last_Name varchar(20) not null,
)
create table Employee
(
Employee_ID int identity(100000,1) primary key,
Person_ID int references Person(Person_ID),
Employee_Type varchar(10)
)
DECLARE #myID AS INT
insert into Person(First_Name, Last_Name) values ('Michael', 'Chu');
SET #myID = ##IDENTITY
insert into Employee(Person_ID, Employee_Type,) values (#myID , 'Admin');

Error while entering data into a table with Primary Key formed by multiple columns, each referenced from other tables

I have 4 tables, 3 of which have their own primary keys. In the 4th table, the primary keys of all the other 3 tables are referenced as foreign keys and these are made into a primary key (combination of all 3 foreign keys). However, upon entering data into the columns, I get constraint violation errors.
The code snippets are as below:
--Table # 1
create table PartSupplier(
partSupplierID int primary key,
fName varchar(20) NOT NULL,
lName varchar(20),
houseNO varchar(20),
streetName varchar(20),
city varchar(20),
dob date,
contactNo varchar(50)
)
--Table # 2
create table PartSpecialist(
partSpecialistID int primary key,
fName varchar(20) NOT NULL,
lName varchar(20),
houseNO varchar(20),
streetName varchar(20),
city varchar(20),
dob date,
contactNo varchar(15)
)
--Table # 3
create table CarPart(
partNumber int primary key,
description varchar (250),
vehicleID int NOT NULL,
imagePath varchar(50)
)
--Table # 4 (with multiple foreign keys made into one primary key)
create table SpecialistSuppliedPart(
partSpecialistID int NOT NULL,
partSupplierID int NOT NULL,
partNumber int NOT NULL,
condition varchar(10),
dateAcquired date,
costPrice int NOT NULL,
constraint specialist_supplier_part_PK primary key (partSpecialistID, partSupplierID, partNumber),
foreign key (partSpecialistID) references PartSpecialist(partSpecialistID),
foreign key (partSupplierID) references PartSupplier(partSupplierID),
foreign key (partNumber) references CarPart(partNumber)
)
I tried inserting the following values in the table:
3 3 5 USED 5000 2011-03-01
3 13 18 NEW 6000 2011-06-26
upon which I got the following error:
http://i.stack.imgur.com/HhFk2.jpg
where FK_SpecialistSuppliedPart_PartSupplier is the Foreign Key existing between Table # 1 and Table # 4.
I have all of these entries existing in the respective tables. After an exhaustive search on the internet (including stackoverflow.com), I could not find a solution.
What am I doing wrong here?
P.S. I tried adding the Foreign and Primary keys using MSSQLs Design Tool but it still results in the same error.

decrement a column from a table while decrement a column from another table

I have 2 tables Aprovizionari (which means Supplies- of books) and Facturi (which means Invoices). The tables have the following structure:
create table Aprovizionari
(
ID_Aprovizionare int identity(1,1) primary key,
CodCarte char(3) foreign key references Carti(CodCarte),
CodLibrarie char(3) foreign key references Librarii(CodLibrarie),
DataAprovizionare date default getdate(),
Cantitate int default 1
-- ^^^^^^^ it should decrement when Cantitate from Facturi increment
)
create table Facturi
(
CodFactura char(3) primary key,
CodClient char(4) foreign key references Clienti(CodClient),
CodCarte char(3) foreign key references Carti(CodCarte),
Cantitate int default 1,
-- ^^^^^^^ value from here must be decrement in Aprovizionari.Cantitate
CodLibrarie char(3) foreign key references Librarii(CodLibrarie),
)
Aprovizionari (Supply) stores the Cantitate (Quantity) of each book in stock.
Each record in Facturi (Invoices) stores a purchase of quantity Cantitate of a particular book.
Books can be identified by CodCarte in both tables.
Everytime an invoice is recorded in Facturi, the quantity of books invoiced should be subtracted from the quantity of the book available in Aprovizionari. How can this be achieved?
If you don't insert Facturi in too many different places it should be quite easy to just perform the update on Aprovizionari after you do the INSERT, e.g.
INSERT INTO Facturi (CodCarte, Cantitate, ...)
VALUES (101, 2);
UPDATE Aprovizionari
SET Cantitate = Cantitate - 2
WHERE CodCarte = 101;
Otherwise you could do this with a trigger along the lines of:
CREATE TRIGGER Facturi_OnInsert
ON Facturi
AFTER INSERT
AS
BEGIN
UPDATE a
SET a.Cantitate = a.Cantitate - i.Cantitate
FROM Aprovizionari a
INNER JOIN INSERTED i ON i.CodCarte = a.CodCarte
END
Just update Aprovizionari table's Cantitate column according to the quantities purchased i.e. From Facturi Table.
Or you can apply a trigger on Facturi table when any new invoice is generated i.e. any new entry in inserted into this table decrease quantity from Aprovizionari table.

Resources