How to properly configure database schema & inserts - sql

So I have the following schema.
CREATE TABLE user_group (
id BIGINT PRIMARY KEY NOT NULL,
user_id BIGINT NOT NULL,
group_table_id BIGINT NOT NULL,
role VARCHAR(255),
CONSTRAINT user_group_user_id_fk FOREIGN KEY (user_id) REFERENCES user(id),
CONSTRAINT user_group_group_table_id_fk FOREIGN KEY (group_table_id) REFERENCES group_table(id)
);
CREATE TABLE group_table
(
id BIGINT PRIMARY KEY NOT NULL,
group_name VARCHAR(255),
group_picture_url VARCHAR(255),
tags VARCHAR(255),
description VARCHAR(255),
event_id BIGINT,
user_group_id BIGINT,
CONSTRAINT group_table_user_group_id_fk FOREIGN KEY (user_group_id) REFERENCES user_group(id)
);
CREATE TABLE user (
id BIGINT PRIMARY KEY NOT NULL,
display_name VARCHAR(255) NOT NULL,
email VARCHAR(255) NOT NULL,
description TEXT NOT NULL,
picture_url VARCHAR(255),
user_group_id BIGINT,
event_response_id BIGINT,
CONSTRAINT user_user_group_id_fk FOREIGN KEY (user_group_id) REFERENCES user_group(id),
);
How can I make it so that this is a valid statement? In the sense that I should be able to create a user_group table, group_table table, or user table without needing the others.
The other question that I have is. Say this statement is valid and the tables exist. How would I insert data into user_group?
INSERT INTO user_group VALUES (1, 2, 3, 'role')
Would require that both a group_table and a user with id's of 2 and 3 respectively already exist upon insert of the value.

How can I make it so that this is a valid statement? In the sense that I should be able to create a user_group table, group_table table, or user table without needing the others.
You can create the tables first, and create the foreign key constraints after. If you try to do both at the same time (like you currently have), you run into a chicken and egg situation.
Here is an example of how you could do it:
CREATE TABLE user_group (
id BIGINT PRIMARY KEY NOT NULL,
user_id BIGINT NOT NULL,
group_table_id BIGINT NOT NULL,
role VARCHAR(255)
);
CREATE TABLE group_table
(
id BIGINT PRIMARY KEY NOT NULL,
group_name VARCHAR(255),
group_picture_url VARCHAR(255),
tags VARCHAR(255),
description VARCHAR(255),
event_id BIGINT,
user_group_id BIGINT
);
CREATE TABLE user (
id BIGINT PRIMARY KEY NOT NULL,
display_name VARCHAR(255) NOT NULL,
email VARCHAR(255) NOT NULL,
description TEXT NOT NULL,
picture_url VARCHAR(255),
user_group_id BIGINT,
event_response_id BIGINT
);
alter table user_group
add constraint user_group_user_id_fk
foreign key (user_id)
references user(id);
alter table user_group
add constraint user_group_group_table_id_fk
foreign key (group_table_id)
REFERENCES group_table(id);
alter table group_table
add constraint group_table_user_group_id_fk
FOREIGN KEY (user_group_id)
REFERENCES user_group(id);
alter table user
add constraint user_user_group_id_fk
FOREIGN KEY (user_group_id)
REFERENCES user_group(id);
The other question that I have is. Say this statement is valid and the tables exist. How would I insert data into user_group?
INSERT INTO user_group VALUES (1, 2, 3, 'role')
Would require that both a group_table and a user with id's of 2 and 3 respectively already exist upon insert of the value.
Yes, the corresponding rows in user (id = 2) and group (id = 3) would have to be inserted prior to attempting the insert into user_group.

Related

How primary key in one table connect to other table with the same primary key?

How primary key in one table connect to another table with the same primary key?
I am trying to make it like this, which those two primary key in the table of CustomerCreditCard is connect to the table of Customer and table of Credit card]
https://i.stack.imgur.com/lIBUE.png
--3
CREATE TABLE Customer
(
CustomerID INT IDENTITY PRIMARY KEY,
FirstName VARCHAR(50) NOT NULL,
LastName VARCHAR(50) NOT NULL,
);
--5
CREATE TABLE CreditCard
(
CreditCardNumber VARCHAR(16) PRIMARY KEY,
CreditCardOwnerName VARCHAR(50) NOT NULL,
);
--6
CREATE TABLE CustomerCreditCard
(
CreditCardNumber VARCHAR(16) NOT NULL,
CustomerID INT IDENTITY NOT NULL,
PRIMARY KEY(CreditCardNumber, CustomerID)
);
--6
CREATE TABLE CustomerCreditCard
(
CreditCardNumber VARCHAR(16) NOT NULL,
CustomerID INT NOT NULL,
CONSTRAINT pk_CustomerCreditCard
PRIMARY KEY(CreditCardNumber,CustomerID ),
CONSTRAINT fk_CustomerCreditCard_CreditCardNumber
FOREIGN KEY(CreditCardNumber)
REFERENCES CreditCard(CreditCardNumber)
ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT fk_CustomerCreditCard_CustomerID
FOREIGN KEY(CustomerID)
REFERENCES Customer(CustomerID)
ON DELETE CASCADE ON UPDATE CASCADE
);
To solve the problem of this question, add the foreign key to the table that has two primary keys, then reference to other tables that you want to connect with the same primary key.

Sql Fiddle errors

I am trying to create SQL statements for an assignment in SQL Fiddle and I keep getting the error "Cannot add foreign key constraint". I have tried various things but I recieve different errors when I change things. What am I doing wrong?
CREATE TABLE Person (
ID int NOT NULL,
FName varchar(255),
LName varchar(255),
Preferred_Name varchar(255),
PRIMARY KEY (ID)
)
;
CREATE TABLE Song (
ID varchar(255) NOT NULL,
Title varchar(255),
Run_Time varchar(255),
Lyrics varchar(255),
LeadID int,
FOREIGN KEY (LeadID) REFERENCES Person(ID),
PRIMARY KEY (ID)
)
;
CREATE TABLE Album (
Title varchar(255) NOT NULL,
Run_Time int,
Release_Year TIMESTAMP,
PRIMARY KEY (Title)
)
;
CREATE TABLE Has (
Album_Title varchar(255),
Song_Title varchar(255),
FOREIGN KEY (Album_Title) REFERENCES Album(Title),
FOREIGN KEY (Song_Title) REFERENCES Song(ID)
)
;
CREATE TABLE Part_Of (
PersonID int,
SongID int,
Role varchar(255) NOT NULL,
FOREIGN KEY (PersonID) REFERENCES Person(ID),
FOREIGN KEY (SongID) REFERENCES Song(ID),
PRIMARY KEY (Role)
)
;
In the Song and Has tables you defined Song.ID and Has.Song_Title as a varchar(255). In the Part_Of table you defined SongID as an int. This is why the foreign key is failing. Use the same datatype in all tables (INT seems like a good option) to fix this.
CREATE TABLE Song (
ID varchar(255) NOT NULL, <------
Title varchar(255),
Run_Time varchar(255),
Lyrics varchar(255),
LeadID int,
FOREIGN KEY (LeadID) REFERENCES Person(ID),
PRIMARY KEY (ID)
)
;
CREATE TABLE Has (
Album_Title varchar(255),
Song_Title varchar(255), <-----
FOREIGN KEY (Album_Title) REFERENCES Album(Title),
FOREIGN KEY (Song_Title) REFERENCES Song(ID)
)
;
CREATE TABLE Part_Of (
PersonID int,
SongID int, <-----
Role varchar(255) NOT NULL,
FOREIGN KEY (PersonID) REFERENCES Person(ID),
FOREIGN KEY (SongID) REFERENCES Song(ID),
PRIMARY KEY (Role)
)
;

SQL, Delete Records Based On Related Fields In Other Table

I have a SQL table based on hotel data. I have two tables and a bridge table to relate them. I'm still learning so I'm sure some of this is not ideal or has potential risks.
Guest Table
CREATE TABLE Guest
(
Guest_ID INT PRIMARY KEY IDENTITY (1, 1),
GuestName NVARCHAR(60) NOT NULL,
Street NVARCHAR(50) NOT NULL,
City NCHAR(30) NOT NULL,
[State] CHAR(2) NOT NULL,
CONSTRAINT [State.State]
FOREIGN KEY ([State]) REFERENCES [State]([State]),
Zip CHAR(5) NOT NULL,
Phone VARCHAR(15) NOT NULL
);
Room Table
CREATE TABLE Room
(
Room_ID SMALLINT PRIMARY KEY,
Room_Type_ID SMALLINT NOT NULL,
CONSTRAINT Room_Type_ID
FOREIGN KEY (Room_Type_ID) REFERENCES Room_Type([Type_ID]),
Amenity_Type_ID SMALLINT NOT NULL,
CONSTRAINT Amenity_Type_ID
FOREIGN KEY (Amenity_Type_ID) REFERENCES Amenity_Type([Type_ID])
);
Bridge Table (Reservations)
CREATE TABLE Guest_Bridge_Rooms
(
Guest_ID INT NOT NULL,
CONSTRAINT Guest_ID
FOREIGN KEY (Guest_ID) REFERENCES Guest(Guest_ID),
Room_ID SMALLINT NOT NULL,
CONSTRAINT Room_ID
FOREIGN KEY (Room_ID) REFERENCES Room(Room_ID),
Date_Start DATE NOT NULL,
Date_End DATE NOT NULL,
Occ_Adults SMALLINT NOT NULL,
Occ_Children SMALLINT NOT NULL,
Price_Total DECIMAL(13,2) NOT NULL
);
Now with these tables, I would like to write a script to DELETE all rows where a reservation (bridged table) has a specific guest NAME by somehow relating the given Guest_ID to its GuestName in the related table. I could simply use Guest_ID but that is not the goal here.
For example something like
DELETE FROM Guest_Bridge_Rooms
WHERE Guest[ID].GuestName = 'John Doe';
Is there a simple way to do this?
You can use a subquery:
DELETE FROM Guest_Bridge_Rooms
WHERE Guest_ID = (SELECT g.Guest_Id FROM Guests g WHERE g.GuestName = 'John Doe');
Note: The exact syntax might vary, depending on the database. This also assumes that GuestName is unique in Guests.

There is no unique constraint matching given keys for referenced table " exam_subjects"

CREATE TABLE student
(
student_id INT PRIMARY KEY,
first_name VARCHAR(40) NOT NULL,
last_name VARCHAR(40) NOT NULL,
birth_day DATE NOT NULL,
sex VARCHAR(1) NOT NULL,
student_email_address VARCHAR(40) NOT NULL UNIQUE,
student_password VARCHAR(10) NOT NULL UNIQUE,
student_nick_name VARCHAR(10) NOT NULL,
student_qualification VARCHAR(10) NOT NULL,
student_documents VARCHAR(255) NOT NULL,
student_image VARCHAR(100) NOT NULL
);
CREATE TABLE student_feedback
(
sr_no BIGSERIAL PRIMARY KEY,
student_id INT NOT NULL,
feedback_type VARCHAR(10) NOT NULL,
feedback_text VARCHAR(200) NOT NULL,
FOREIGN KEY (student_id) REFERENCES student(student_id)
);
CREATE TABLE online_exam
(
exam_id INT PRIMARY KEY,
exam_title VARCHAR(20) UNIQUE NOT NULL,
exam_duration_min INT NOT NULL,
total_questions INT NOT NULL,
marks_per_right_answer INT NOT NULL,
marks_per_wrong_answer INT NOT NULL,
passing_marks INT NOT NULL,
exam_status VARCHAR(2)
);
CREATE TABLE exam_subjects
(
sub_id INT,
exam_id INT,
sub_name VARCHAR(20) NOT NULL,
sub_desc VARCHAR(20) NOT NULL,
UNIQUE(sub_id,exam_id),
PRIMARY KEY(sub_id,exam_id),
FOREIGN KEY (exam_id) REFERENCES online_exam(exam_id) ON DELETE CASCADE
);
CREATE TABLE sub_questions
(
sub_id1 INT,
ques_id INT,
ques_text VARCHAR(150) NOT NULL,
ques_attachments VARCHAR(255),
option_1 VARCHAR(20) NOT NULL,
option_2 VARCHAR(20) NOT NULL,
option_3 VARCHAR(20) NOT NULL,
option_4 VARCHAR(20) NOT NULL,
UNIQUE(sub_id1,ques_id),
PRIMARY KEY (sub_id1,ques_id),
FOREIGN KEY (sub_id1) REFERENCES exam_subjects(sub_id) ON DELETE CASCADE
);
CREATE TABLE ques_answers
(
ans_id INT,
ques_id INT,
ans VARCHAR(20) NOT NULL,
PRIMARY KEY (ans_id,ques_id),
FOREIGN KEY (ques_id) REFERENCES sub_questions(ques_id) ON DELETE CASCADE
);
CREATE TABLE exam_registration
(
student_id INT,
exam_id INT,
exam_date_time TIMESTAMP NOT NULL,
PRIMARY KEY (student_id,exam_id),
FOREIGN KEY (student_id) REFERENCES student(student_id) ON DELETE CASCADE,
FOREIGN KEY (exam_id) REFERENCES online_exam(exam_id) ON DELETE CASCADE
);
CREATE TABLE exam_result
(
student_id INT,
exam_id INT,
sub_id INT,
marks_scored INT NOT NULL,
correct_ques INT NOT NULL,
wrong_ques INT NOT NULL,
grade VARCHAR(10) NOT NULL,
PRIMARY KEY(student_id,exam_id,sub_id),
FOREIGN KEY (student_id) REFERENCES student(student_id) ON DELETE CASCADE,
FOREIGN KEY (exam_id) REFERENCES online_exam(exam_id) ON DELETE CASCADE,
FOREIGN KEY (sub_id) REFERENCES exam_subjects(sub_id) ON DELETE CASCADE
);
Output :
CREATE TABLE,
CREATE TABLE,
CREATE TABLE,
CREATE TABLE,
There is no unique constraint matching given keys for referenced table "exam_subjects", relation "sub_questions" do not exist,
CREATE TABLE,
There is no unique constraint matching given keys for referenced table "exam_subjects".
Why am I getting "there is no unique..." error in postgresql? How to solve it? Please help.
In your table exam_subjects the primary key is a compossed key (PRIMARY KEY(sub_id, exam_id))
Therefore, your table sub_questions must have both columns to create the constraint, otherwise you get the error about unique constraints (or you can create a unique field acting as primary key, and create a unique index on both columns sub_id and exam_id)

SQL how can I get list of users and departments with filter by position?

Please help me, how can i get a list of users of the department with a filter by position?
CREATE TABLE COMPANY
(
ID INT GENERATED BY DEFAULT AS IDENTITY,
NAME VARCHAR(255),
PRIMARY KEY (ID),
UNIQUE KEY COMPANY_NAME (NAME)
);
CREATE TABLE USER
(
ID INT GENERATED BY DEFAULT AS IDENTITY,
NAME VARCHAR(255),
LASTNAME VARCHAR(255),
DATE_OF_BIRTH DATE ,
PRIMARY KEY (ID),
);
CREATE TABLE POSITION
(
ID INT NOT NULL GENERATED BY DEFAULT AS IDENTITY,
POSITION VARCHAR (50),
USERID INT NOT NULL,
PRIMARY KEY (ID),
FOREIGN KEY (USERID) REFERENCES USER(ID)
);
CREATE TABLE DEPARTMENT
(
ID INT GENERATED BY DEFAULT AS IDENTITY,
USER_ID INT NOT NULL,
COMPANY_ID INT NOT NULL,
DEPARTMENT_CATEGORY VARCHAR(50),
PRIMARY KEY (ID),
FOREIGN KEY (USER_ID) REFERENCES USER(ID),
FOREIGN KEY (COMPANY_ID) REFERENCES COMPANY(ID)
);
CREATE TABLE CATEGORY
(
ID INT NOT NULL GENERATED BY DEFAULT AS IDENTITY,
NAME VARCHAR (50),
PRIMARY KEY (ID)
);
CREATE TABLE DEPARTMENT_CATEGORY
(
DEPARTMENT_ID INT NOT NULL,
CATEGORY_ID INT NOT NULL,
FOREIGN KEY (DEPARTMENT_ID) REFERENCES DEPARTMENT(ID),
FOREIGN KEY (CATEGORY_ID) REFERENCES CATEGORY(ID)
);
Please help me!!
it look like you wanted to display results from department and position table that has both the data you need, but be specific about your filter (position) as u need to provide it in your where clause
select user_ID, department
from department as a
join user as b
on a. user_id = b. user_id
where position = 'put the specific position you wanted to be filtered here'
but your two userID columns are written differently as (User_id or USERID) correct that too not get failure result when you execute the task