How do i fill my table with data from 3 different tables? - sql

So I am working on a football world cup database. These are my important tables:
CREATE TABLE Countries(
Cid SERIAL PRIMARY KEY,
Name VARCHAR(256) NOT NULL UNIQUE
);
CREATE TABLE Stadiums(
Sid SERIAL PRIMARY KEY,
Name VARCHAR(256) NOT NULL UNIQUE,
Cid INT REFERENCES Countries NOT NULL
);
CREATE TABLE Groups(
Gid SERIAL PRIMARY KEY,
Name VARCHAR(64) NOT NULL,
TYear SMALLINT REFERENCES Tournaments NOT NULL
);
CREATE TABLE Teams(
Tid SERIAL PRIMARY KEY,
Cid INT REFERENCES Countries NOT NULL,
Gid INT REFERENCES Groups NOT NULL
);
CREATE TABLE Matches(
Mid INT PRIMARY KEY,
HomeTid INT REFERENCES Teams NOT NULL,
VisitTid INT REFERENCES Teams NOT NULL,
HomeScore SMALLINT NOT NULL,
VisitScore SMALLINT NOT NULL,
MatchDate DATE NOT NULL,
MatchType VARCHAR(64) NOT NULL,
Sid INT REFERENCES Stadiums NOT NULL
);
CREATE TABLE tempmatches(
year INTEGER,
host_country VARCHAR(255),
match_id INTEGER,
type VARCHAR(255),
date DATE,
location1 VARCHAR(255),
team1 VARCHAR(255),
team2 VARCHAR(255),
score1 INTEGER,
score2 INTEGER
);
so my current problem is that I need to populate the columns HomeTid and VisitId of the Matches table with the tid's from the team's table that corresponds with the country of that team from the countries table but I'm not sure how to do that. I tried a few queries but none of them seemed to work. Has anyone an idea on how to solve this?

Using JOIN keyword you can combine 2 tables data.
Here, in this case, you have to use 3-way join.
Eg:
3-way JOIN can be used in this way:
SELECT * FROM table1 JOIN table2 ON table1.col1=table2.col2 JOIN table3 ON table3.col3=table.col1;
Here the 2 tables will get joined based on the columns mentioned after the "ON" keyword.
Here is a reference link in which JOIN is explained clearly
https://www.w3schools.com/sql/sql_join.asp

Use JOIN operation. In SQL it helps to combine several tables(queries) in one

Related

ALTER TABLE statement conflicted with the FOREIGN KEY constraint

When creating the foreign key I came across this error. Below is my code.
create table tblPerson(
ID int not null primary key,
Fullname varchar(50) not null,
Email varchar(50) not null,
GenderId int
)
create table tblGender (
ID int not null primary key,
Gender varchar(50) not null
)
alter table tblPerson add constraint tblPerson_GenderId_FK
foreign key (GenderId) references tblGender(ID)
You want to identify any "do not align" rows....
I have made the below.
You won't be able to add the FK constraint, if any rows come back from the SELECT query.
I have also removed the hungarian notation for "tbl". I would advise against it.
create table dbo.Person(
ID int not null primary key,
Fullname varchar(50) not null,
Email varchar(50) not null,
GenderId int )
create table dbo.Gender (
ID int not null primary key,
Gender varchar(50) not null
)
/* any rows below? your FK creation will fail */
Select *, p.GenderId as 'HoustonWeHaveAProblemValue' from dbo.Person p Where Not Exists (Select 1 from dbo.Gender g where g.ID = p.GenderId)
alter table dbo.Person add constraint Person_GenderId_FK
foreign key (GenderId) references dbo.Gender(ID)
Hi please use the following code to achieve your goal :
1-First create tblGender:
create table tblGender (
ID int not null primary key,
Gender varchar(50) not null
)
2-Then create table tblPerson with the relationship between 2 tables since the beginning:
create table tblPerson(
ID int not null primary key,
Fullname varchar(50) not null,
Email varchar(50) not null,
GenderId int references tblGender(ID)
)
works fine.

I need to JOIN using a linking table

The three tables are as follows:
CREATE TABLE Artist
(
ArtistKey char(20) NOT NULL PRIMARY KEY,
ArtistName varchar(50) NOT NULL
)
CREATE TABLE AlbumInfo
(
AlbumInfoKey char(20) NOT NULL PRIMARY KEY,
AlbumTitle varchar(50) NOT NULL,
AlbumDate date NULL,
AlbumStudio varchar(50) NULL
)
CREATE TABLE AlbumArtist
(
AlbumInfoKey char(20) NOT NULL,
ArtistKey char(20) NOT NULL,
PRIMARY KEY CLUSTERED
(
AlbumInfoKey ASC,
ArtistKey ASC
))
My objective is to list all of the artists and their albums. I can't seem to get anything to work.
I have tried:
SELECT
Artist.ArtistName,
AlbumInfo.AlbumTitle
FROM Artist
JOIN AlbumArtist
ON Artist.ArtistKey = AlbumArtist.ArtistKey
JOIN AlbumInfo
On AlbumInfo.AlbumInfoKey = AlbumArtist.AlbumInfoKey
However this gives me back nothing not even an error.
Alright, I had to re-do your whole task, and I have come up with more professional, and better way of managing database. You need to drop those tables, and re-do whole thing like show in code below :
--First create Artist table
CREATE TABLE Artist
(
Artist_key int PRIMARY KEY IDENTITY(1,1),
ArtistName varchar(50) NOT NULL,
);
--Then create Album table
CREATE TABLE AlbumInfo
(
Album_key int NOT NULL PRIMARY KEY IDENTITY(1,1),
AlbumTitle varchar(50) NOT NULL,
AlbumDate date NULL,
AlbumStudio varchar(50) NULL,
Artist_key int FOREIGN KEY (Artist_key) REFERENCES Artist(Artist_key)
);
-- Must have Artist data before referencing in the album table
INSERT into Artist (ArtistName) values ('John')
INSERT into AlbumInfo (AlbumTitle,AlbumDate,AlbumStudio,Artist_key) values ('ABC3','2020-6-12','Def3',(select Artist_key from Artist where Artist_key = 1 ))
--test if data has been inserted
SELECT * FROM Artist
SELECT * FROM AlbumInfo
-- And finally this query will show the Artist with their relevant Albums
SELECT ArtistName,af.AlbumTitle,AlbumStudio from Artist a join AlbumInfo af on af.Artist_key = a.Artist_key
And the result is :

Is there a way to relationship between two table which table one has 3 unique keys and table two has 2 unique keys in SQL Server?

I want to create relation between two tables, here's my table structure
Table1:
ID INT PrimaryKey AUTO_INCREMENT,
CountryCode INT UNIQUE,
Division VARCHAR(4) UNIQUE,
SubDivision VARCHAR(10) UNIQUE
Table2:
ID INT PrimaryKey AUTO_INCREMENT,
CountryCode INT UNIQUE,
Division VARCHAR(4) UNIQUE,
ReportNo VARCHAR(10) UNIQUE
Table1:
ID |CountryCode |Division |SubDivision
-------+------------------+--------------+-----------
1 |IDN |A |A-1
2 |IDN |B |B-1
3 |IDN |B |B-2
Table2
ID |CountryCode |Division |ReportNo
-------+------------------+--------------+-----------
1 |IDN |A |Re001
2 |IDN |A |Re002
3 |IDN |B |Re003
I want to create a relationship between those two tables which table2 (CountryCode, Division) refers to table1 (CountryCode, Division).
So when I want to delete in table1 with CountryCode = IDN and Division = A, SQL will prompt error when table2 contains CountryCode = IDN and Division = A.
I had tried to create a relationship between those two tables, but SQL Server always throws this error:
The column in table 'table1' do not match an existing primary key or unique constraint
Can anyone guide me how can I create a relationship between those two tables?
Thanks in advance
You can't do it this way. SQL Server requires a unique constraint (or primary key constraint) on the target of a foreign key - and you have duplicates in the source table.
For this to work, you would need to have a separate table that references all possible (CountryCode, Division) combinations. Actually, your whole schema should be normalized into something like:
-- "top" table that stores the countries
create table countries (
country_id int primary key
name varchar(100)
);
-- the table that stores the divisions
create table divisions (
division_id int primary key,
country_id int references countries(country_id),
name varchar(100)
);
-- the table that stores the subdivisions
-- this corresponds to "table1" in your question
create table subdivisions (
subdivision_id int primary key,
division_id int references divisions(division_id),
name varchar(100)
);
-- the table that stores the reports
-- this corresponds to "table2" in your question
create table reports (
report_id int primary key,
division_id references divisions(division_id),
name varchar(100)
);
You can make the primary keys automatic by using identity columns (which is the SQL Server equivalent for MySQL's AUTO_INCREMENT).
As an example, here is how you would generate the current output that you are showing for the subdivisions:
select
sd.id,
c.name country,
d.name division,
sd.name subdivision
from subdivisions sd
inner join divisions d on d.division_id = sd.division_id
inner join countries c on c.country_id = d.country_id
As GMB has answered you cannot do it in this way because of the duplicates. GMB's answer is the best way to solving your problem. If for some reason you cannot follow his advice then maybe my answer would help.
You could use a composite primary key on the columns CountryCode, Division, SubDivision. Then add subdivision to Table2. And then reference this primary key in the foreignkey restraint. (notice that my example throws an error on purpose to show that the value cannot be deleted)
DROP TABLE IF EXISTS Table2;
DROP TABLE IF EXISTS Table1;
CREATE TABLE Table1
(ID INT IDENTITY(1,1)
, CountryCode CHAR(3)
, Division VARCHAR(4)
, SubDivision VARCHAR(10)
, CONSTRAINT PK_Table1 PRIMARY KEY(CountryCode, Division, SubDivision)
)
INSERT INTO Table1(CountryCode, Division, SubDivision)
VALUES ('IDN', 'A', 'A-1')
, ('IDN', 'B', 'B-1')
, ('IDN', 'B', 'B-2');
CREATE TABLE Table2
(ID INT IDENTITY(1,1) PRIMARY KEY
, CountryCode CHAR(3)
, Division VARCHAR(4)
, SubDivision VARCHAR(10)
, ReportNo VARCHAR(10)
, CONSTRAINT FK_CountryDivision FOREIGN KEY(CountryCode, Division, SubDivision) REFERENCES Table1(CountryCode, Division, SubDivision)
);
INSERT INTO Table2(CountryCode, Division, SubDivision, ReportNo)
VALUES ('IDN', 'A', 'A-1', 'Re001')
, ('IDN', 'B', 'B-1', 'Re002')
, ('IDN', 'B', 'B-2', 'Re003');
DELETE FROM Table1
WHERE Division = 'A';
Of course this change could add a whole set of new problems for instance when a report is for the whole division what should the subdivision value then be.
ps. i had to change up the example tables a bit because the values did not match, ie string values into an int column.
SQL fiddle
thank you for the all greats answer.
But in my design I can't doing this, because I has been wrong at the first time.
And the greats answer was from Mr. #10676716 #GMB.
-- "top" table that stores the countries
create table countries (
country_id int primary key
name varchar(100)
);
-- the table that stores the divisions
create table divisions (
division_id int primary key,
country_id int references countries(country_id),
name varchar(100)
);
-- the table that stores the subdivisions
-- this corresponds to "table1" in your question
create table subdivisions (
subdivision_id int primary key,
division_id int references divisions(division_id),
name varchar(100)
);
-- the table that stores the reports
-- this corresponds to "table2" in your question
create table reports (
report_id int primary key,
division_id references divisions(division_id),
name varchar(100)
);
Thanks again Mr. GMB.

Problems with a query PostgreSQL

I have some problems with a Query that I can not get out, the structure of the tables is as follows:
child
CREATE TABLE CHILD(
child_id SMALLINT,
child_name VARCHAR(255) NOT NULL,
birth_date DATE NOT NULL,
gender VARCHAR(255) NOT NULL,
address VARCHAR(255),
city VARCHAR(255),
CONSTRAINT PK_CHILD PRIMARY KEY(child_id)
letter
CREATE TABLE LETTER(
letter_id SMALLINT,
arrival_date DATE NOT NULL,
number_toys INTEGER NOT NULL,
delivery_mode VARCHAR(255) NOT NULL,
child_id SMALLINT,
CONSTRAINT PK_LETTER PRIMARY KEY(letter_id),
CONSTRAINT CHILD_FK FOREIGN KEY (child_id) REFERENCES CHILD(child_id)
);
wished_toy
CREATE TABLE WISHED_TOY(
letter_id SMALLINT,
toy_id SMALLINT,
CONSTRAINT PK_WISHED_TOY PRIMARY KEY(letter_id, toy_id),
CONSTRAINT LETTER_FK FOREIGN KEY (letter_id) REFERENCES LETTER(letter_id)
CONSTRAINT LETTER_FK FOREIGN KEY (toy_id) REFERENCES TOY(toy_id)
);
toy
CREATE TABLE TOY(
toy_id SMALLINT,
toy_name VARCHAR (255) NOT NULL,
price DECIMAL NOT NULL,
toy_type VARCHAR(255) NOT NULL,
manufacturer VARCHAR(255) NOT NULL,
CONSTRAINT PK_TOY PRIMARY KEY(toy_id),
);
I have to design a query that allows to obtain for each girl born before 2010 the
total number of toys you have ordered. The result must also include
those girls who have not written any letters. Specifically we want the
identifier of the girl, her name and city and the total number of toys ordered
(such as Total_number).
in the gender column of the child table can only be "m" of masculine or "f" of feminine
Do I have to use join?
the part that I have is this
select c.child_id,c.child_name,c.city
from letter l
join child c
on c.child_id=l.child_id
where c.gender='m' and c.birth_date between <='2010/01/01';
select c.child_id,c.child_name,c.city, coalesce( number_toys,0) counted
from
Child c
left outer join letter l
on c.child_id=l.child_id
where c.gender='m' and c.birth_date between <='2010/01/01';
Or
select c.child_id,c.child_name,c.city, count(wt.letter_id) actualToys
from
Child c
left outer join letter l
on c.child_id=l.child_id
left outer join wished_toy wt on l.letter_id=wt.letter_id
where c.gender='m' and c.birth_date between <='2010/01/01'
Group by
c.child_id,c.child_name,c.city
To count the toys referenced by database rows rather than the pre defined count

How to organize tables to stare statistic of two entities?

For now I have only two tables
CREATE TABLE IF NOT EXISTS company (
id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
name VARCHAR (250) NOT NULL
);
CREATE TABLE IF NOT EXISTS employee (
id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
name VARCHAR (250),
company_id INT,
FOREIGN KEY (company_id) REFERENCES Company (id)
);
I need to create one or two tables to store employees and companies statistic. For employee statistic I need to remember all previous companies of this employee and of cause hire dates and resign dates. For company statistic I need to remember all resigned employees. What is the best way to organize DB structure in my case?
Since you have many-to-many relationship, you need an aggregate table company_employee that will have combined primary key, so you need:
CREATE TABLE IF NOT EXISTS company (
id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
name VARCHAR (250) NOT NULL
);
CREATE TABLE IF NOT EXISTS employee (
id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
name VARCHAR (250)
);
CREATE TABLE IF NOT EXISTS company_employee (
company_id INT NOT NULL,
employee_id INT NOT NULL,
hire_date DATE,
resign_date DATE,
FOREIGN KEY (company_id) REFERENCES Company (id),
FOREIGN KEY (employee_id) REFERENCES Employee (id)
);
So, if you want anything from aggregate table, just use JOIN on key of appropriate table.