Using inner join as ALIASES with multiple tables - sql

I have these tables below:
create table student(
studentName varchar (40) not null,
studentRollNo varchar (30) primary key, -- also acts as username
studentPassword varchar(30) NOT NULL,
studentGender varchar(7) default NULL
);
create table supervisors(
supervisorID varchar(30) foreign key references Faculty(facultyID) unique,
sWorkLoad int default null,
CHECK (sWorkLoad<=6 and sWorkLoad>=0)
);
create table co_supervisors(
co_supervisorID varchar(30) foreign key references Faculty(facultyID) unique,
csWorkLoad int default null,
CHECK (csWorkLoad<=6 and csWorkLoad>=0)
);
create table studentGroup(
groupID int IDENTITY(1,1) primary key ,
Member1rollNo varchar(30) foreign key references student(studentRollNo) default NULL, -- member 1
Member2rollNo varchar(30) foreign key references student(studentRollNo) default NULL, -- member 2
Member3rollNo varchar(30) foreign key references student(studentRollNo) default NULL, -- member 3
supervID varchar(30) foreign key references supervisors(supervisorID),
co_supervID varchar(30) foreign key references co_supervisors(co_supervisorID) default NULL,
projectTitle varchar(100) not null,
projectDetails varchar (500) default NULL
);
create table FYP1(
groupID int foreign key references studentGroup(groupID),
);
I want to display student details who are registered in FYP1.
with their supervisors, co_supervisors,and project title.
But I I'm not able to do so,
What I have done so far is this.
select sg.Member1rollNo,S.studentName,Member2rollNo,S.studentName,sg.Member3rollNo,sg.supervID,sg.projectTitle
FROM student S
inner join studentGroup SG ON S.studentRollNo = SG.Member1rollNo
OR some random tries like this
-- Faculty.facultyName
SELECT FYP1.groupID, studentGroup.Member1rollNo,student.studentName as student1, studentGroup.Member2rollNo,student.studentName as student2,studentGroup.projectTitle
FROM FYP1 as FYP1_Students
INNER JOIN studentGroup ON (studentGroup.groupID = FYP1_Students.groupID)
INNER JOIN supervisors ON (studentGroup.supervID = supervisors.supervisorID)
INNER JOIN student ON (student1.studentRollNo = studentGroup.Member1rollNo)
INNER JOIN student ON (student.studentRollNo = studentGroup.Member2rollNo)
Output or first query is this (example):
'i19-0434' 'Sourav Malani' 'i19-0498' 'Sourav Malani' NULL 'urooj.ghani' 'Indoor Navigation'
'i19-0466' 'Aftab Ali' 'i19-0528' 'Aftab Ali' NULL 'urooj.ghani' 'AI based Physics exp.'
I want output to be like:
'i19-0434' 'Sourav Malani' 'i19-0498' 'Student2 Name' NULL 'urooj.ghani' 'Indoor Navigation'
'i19-0466' 'Aftab Ali' 'i19-0528' '<student2Name>' NULL 'urooj.ghani' 'AI based Physics exp.'
Sample Data
Thanks to #Hana, I solved the problem.
Here's the solution:
SELECT SG.groupID,
SG.Member1rollNo,S1.studentName as 'student1 Name',
SG.Member2rollNo, S2.studentName as 'student2 Name',
SG.Member3rollNo, S3.studentName as 'Studen3 Name',
SG.supervID, SN.facultyName as 'Supervisor Name',
SG.co_supervID, CSN.facultyName as 'Co_Supervisor',
SG.projectTitle as 'Project Title',
SG.projectDetails as 'Project Desc.'
FROM FYP1 FYP1
LEFT OUTER JOIN studentGroup SG ON FYP1.groupID = SG.groupID
LEFT OUTER JOIN supervisors SV ON SG.supervID = SV.supervisorID
LEFT OUTER JOIN Faculty SN ON SG.supervID= SN.facultyID
LEFT OUTER JOIN Faculty CSN ON SG.co_supervID= CSN.facultyID
LEFT OUTER JOIN student S1 ON SG.Member1rollNo = S1.studentRollNo
LEFT OUTER JOIN student S2 ON SG.Member2rollNo = S2.studentRollNo
LEFT OUTER JOIN student S3 ON SG.Member3rollNo = S3.studentRollNo

Is this what you are looking for?
SELECT SG.groupID, SV.supervisorID, CSV.co_supervisorID, S1.studentName, S2.studentName, S3.studentName
FROM FYP1 FYP1
INNER JOIN studentGroup SG ON FYP1.groupID = SG.groupID
INNER JOIN supervisors SV ON SG.supervID = SV.supervisorID
INNER JOIN co_supervisors CSV ON SG.co_supervID = CSV.co_supervisorID
INNER JOIN student S1 ON SG.Member1rollNo = S1.studentRollNo
INNER JOIN student S2 ON SG.Member1rollNo = S2.studentRollNo
INNER JOIN student S3 ON SG.Member1rollNo = S3.studentRollNo

Related

Sqlite SQL Statement Not Working As I Expecting

Im using sqlite3 database and i try to get data from two table with cross join.
They have some foreign keys and i can`t get reference value
for currency names (b_currency and s_currency).
They need to be like 'USD','EUR','TRL' etc.
SQL STATEMENT:
select
a.pid,
person.fullname,
a.amount as b_amount,
b.amount as s_amount,
a.currency as b_currency,
b.currency as s_currency,
a.rate as b_rate,
b.rate as s_rate,
`user`.username,
a.`date`
from buy_process as a
inner join person
on a.fullname=person.id
inner join currency
on b_currency=currency.id and s_currency=currency.id
inner join `user`
on a.`user`=`user`.id
cross join sell_process as b
where a.pid=b.pid;
BUY_PROCESS AND SELL_PROCESS TABLE FIELDS ARE SAME:
-- Describe BUY_PROCESS
CREATE TABLE `buy_process`(
id integer primary key AUTOINCREMENT,
pid VARCHAR(50) NOT NULL UNIQUE,
fullname INTEGER NOT NULL,
amount VARCHAR(50) NOT NULL,
currency INTEGER NOT NULL,
rate VARCHAR(50) NOT NULL,
`user` INTEGER NOT NULL,
`date` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT fkbuy_fullname FOREIGN KEY(fullname) REFERENCES person(id),
CONSTRAINT fkbuy_currency FOREIGN KEY(currency) REFERENCES currency(id),
CONSTRAINT fkbuy_user FOREIGN KEY(`user`) REFERENCES `user`(id)
);
RESULT:
Result image
I tried to change field names but i did not succeed:
a.pid,
person.fullname,
a.amount as b_amount,
b.amount,
currency.name as b_currency,
currency.name as s_currency,
a.rate as b_rate,
b.rate as s_rate,
`user`.username,
a.`date`
from buy_process as a
inner join person
on a.fullname=person.id
inner join currency
on b_currency=currency.id and s_currency=currency.id
inner join `user`
on a.`user`=`user`.id
cross join sell_process as b
where a.pid=b.pid;
I don't understand what you want to achieve with the cross join (you have a condition a.pid=b.pid, why not just inner join them?).
You need to join the currency table twice, once for the buy currency, and once for the sell currency:
select
...
b_cncy.name as b_currency,
s_cncy.name as s_currency,
...
from
buy_process as bp
inner join
sell_process as sp
on bp.pid=sp.pid
inner join
currency b_cncy
on b_cncy.id=bp.currency
inner join currency s_cncy
on s_cncy.id=sp.currency
inner join `user` usr
on usr.id=bp.`user`

I need to create a view that pre-joins the three tables, including all of the records from student and course tables ( shown below) [duplicate]

This question already has answers here:
Error report - ORA-25155: column used in NATURAL join cannot have qualifier 25155. 00000 - "column used in NATURAL join cannot have qualifier"
(2 answers)
Closed 2 years ago.
-- I am trying to create a view for the tables shown below but my attempt is not successfull. I am using Oracle SQL Developer!! Where is the mistake here
CREATE VIEW student_view AS
SELECT Student.*, Course.*, Grade.* FROM (Student NATURAL LEFT OUTER JOIN Grade NATURAL LEFT OUTER JOIN Course)
UNION ALL
SELECT Student.*, Course.*, Grade.* FROM (Course NATURAL LEFT OUTER JOIN Grade NATURAL LEFT OUTER JOIN Student) WHERE Student.StudentID is NULL
;
CREATE TABLE Student(
StudentID INT PRIMARY KEY NOT NULL,
Name CHAR(50),
Address CHAR(50),
GradYear INT
);
-- create table Grade
CREATE TABLE Grade(
CName CHAR(50) NOT NULL,
StudentID INT NOT NULL,
CGrade CHAR(2),
PRIMARY KEY(CName, StudentID)
);
-- create table Course
CREATE TABLE Course(
CName CHAR(50) PRIMARY KEY NOT NULL,
Department CHAR(50),
Credits INT
);
You should create the underlying tables before composing them into a view.
Please follow below sequence,
CREATE TABLE Student(
StudentID INT PRIMARY KEY NOT NULL,
Name CHAR(50),
Address CHAR(50),
GradYear INT
);
-- create table Grade
CREATE TABLE Grade(
CName CHAR(50) NOT NULL,
StudentID INT NOT NULL,
CGrade CHAR(2),
PRIMARY KEY(CName, StudentID)
);
-- create table Course
CREATE TABLE Course(
CName CHAR(50) PRIMARY KEY NOT NULL,
Department CHAR(50),
Credits INT
);
CREATE VIEW student_view AS
SELECT Student.StudentID , Student.Name, Student.Address, Student.GradYear,
Course.CName, Course.CGrade, Grade.Department, Grade.Credits FROM Student
LEFT OUTER JOIN Grade
on (Student.StudentID = Grade.StudentID)
LEFT OUTER JOIN Course
on (Grade.CName = Course.CName);
Corrected version:
Defined tables in the right order
Changed CHAR to VARCHAR2
Added foreign key constraints (inheriting data types)
Removed table aliases not allowed by NATURAL JOIN syntax
Removed redundant brackets from view.
Tables:
create table student
( studentid integer primary key not null
, name varchar2(50) not null
, address varchar2(50)
, gradyear integer );
create table course
( cname varchar2(50) primary key not null
, department varchar2(50)
, credits integer );
create table grade
( cname references course not null
, studentid references student not null
, cgrade varchar2(2) not null
, primary key(cname, studentid) );
View:
create or replace view student_view as
select studentid, name, address, gradyear
, cname, department, credits
, cgrade
from student
natural left outer join grade
natural left outer join course
union all
select studentid, name, address, gradyear
, cname, department, credits
, cgrade
from course
natural left outer join grade
natural left outer join student
where studentid is null;
And just to add, NATURAL JOIN is never a good idea in real code.

Joins on multiple tables in Postgresql

I'm practising for an upcoming database exam and I'm trying to get my head around nested and multiple joins in SQL, specifically the Postgresql syntax. I want to return all the student names and department names of all students that achieved grade A.
Here's my schema.
CREATE TABLE student1 (
student_number INTEGER NOT NULL PRIMARY KEY,
name TEXT NOT NULL,
class INTEGER NOT NULL,
major TEXT NOT NULL
);
CREATE TABLE course1 (
course_name TEXT NOT NULL,
course_number TEXT NOT NULL PRIMARY KEY,
credit_hours INTEGER NOT NULL,
department TEXT NOT NULL
);
CREATE TABLE section1 (
section_identifer INTEGER NOT NULL PRIMARY KEY,
course_number TEXT NOT NULL,
semester TEXT NOT NULL,
year INTEGER NOT NULL,
instructor TEXT NOT NULL,
FOREIGN KEY (course_number) REFERENCES course1(course_number) ON DELETE CASCADE
);
CREATE TABLE grade_report1 (
id SERIAL NOT NULL PRIMARY KEY,
student_number INTEGER NOT NULL,
section_identifer INTEGER NOT NULL,
grade TEXT NOT NULL,
FOREIGN KEY (student_number) REFERENCES student1(student_number) ON DELETE CASCADE,
FOREIGN KEY (section_identifer) REFERENCES section1(section_identifer) ON DELETE CASCADE
);
I put together a nested statement that I thought would work:
SELECT t1.name, t3.department
FROM (student1 t1 INNER JOIN grade_report1 t2 ON t1.student_number = t2.student_number) t5
INNER JOIN (course1 t3 INNER JOIN section1 t4 ON t3.course_number = t4.course_number) t6
ON t5.section_identifer = t6.section_identifer
WHERE t2.grade = 'A';
However, this gives me the error invalid reference to FROM-clause entry for table "t1". I'm guessing it is because that is not how you are supposed to name/reference JOINS. I would like a way to JOIN all of these tables together. Thanks!
Remove the parentheses and fix the aliases:
SELECT s.name, c.department
FROM student1 s INNER JOIN
grade_report1 gr
ON gr.student_number = s.student_number INNER JOIN
section1 sec
ON sec.section_identifer = gr.section_identifer INNER JOIN
course1 c
ON sec.course_number = c.course_number
WHERE gr.grade = 'A';
The parentheses are allowed, but they are not needed. When using parentheses (which is very, very rarely needed), they do not get separate aliases.

How to select just parent and not inherit values

I have 3 tables. Game, FinalGame which extends Game and Participant who has list of game and list of FinalGame. Now I have problem. How to select just game and not finalGame. How to select Participant with just game and not finalGame.
In first option I tried:
select * from game g where {g.ID not in (select pl.game_id from PLAY_OFF_TABLE pl) }
but I am not sure if it is right.
In second option I tried;
select * from participant p left join game g1 on p.ID = g1.HOME_PARTICIPANT_ID
but this select all games including final. I have no idea how I can exclude final game
CREATE TABLE IF NOT EXISTS `GAME` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`HOME_PARTICIPANT_ID` int(11) DEFAULT NULL,
`AWAY_PARTICIPANT_ID` int(11) DEFAULT NULL,
`STATUS` enum('WIN','LOSE','DRAW') DEFAULT NULL,
`RESULT` varchar(50) DEFAULT NULL,
PRIMARY KEY (`ID`),
KEY `HOME_PARTICIPANT_ID` (`HOME_PARTICIPANT_ID`),
KEY `AWAY_PARTICIPANT_ID` (`AWAY_PARTICIPANT_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=10 ;
CREATE TABLE IF NOT EXISTS `PLAY_OFF_GAME` (
`GAME_ID` int(11) NOT NULL,
`GROUP_ID` int(11) NOT NULL,
`POSITION` int(11) NOT NULL,
PRIMARY KEY (`GAME_ID`),
KEY `GROUP_ID` (`GROUP_ID`),
KEY `POSITION` (`POSITION`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `PARTICIPANT` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
...
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=10 ;
UPDATE:
select * from PARTICIPANT p left join GAME g1 on p.ID = g1.HOME_PARTICIPANT_ID join PLAY_OFF_GAME pl on g1.id = pl.GAME_ID where p.group_id = 441 and pl.GAME_ID is null
retun 0 rows
select * from PARTICIPANT p left join GAME g1 on p.ID = g1.HOME_PARTICIPANT_ID left join PLAY_OFF_GAME pl on g1.id = pl.GAME_ID where p.group_id = 441 and pl.GAME_ID is null
return 5
select * from PARTICIPANT p left join GAME g1 on p.ID = g1.HOME_PARTICIPANT_ID left join PLAY_OFF_GAME pl on g1.id = pl.GAME_ID where p.group_id = 441
return all participant 8 but also final game which I want to exclude
Your first query would select GAME rows that do not have a corresponding PLAY_OFF_GAME, but a join is probably much quicker:
SELECT *
FROM GAME g
LEFT JOIN PLAY_OFF_GAME pog ON g.ID=pog.GAME_ID
WHERE pog.GAME_ID IS NULL;
For the second question, you can do the same trick:
SELECT * FROM (
(SELECT p1.*, g.ID
FROM PARTIPANT p1
LEFT JOIN GAME g1 ON p1.ID=g1.HOME_PARTICIPANT_ID
LEFT JOIN PLAY_OFF_GAME pog1 ON g1.ID=pog1.GAME_ID
WHERE pog1.GAME_ID IS NULL)
UNION
(SELECT p2.*, NULL
FROM PARTICIPANT p2
JOIN GAME g2 ON p2.ID=g2.HOME_PARTICIPANT_ID
JOIN PLAY_OFF_GAME pog2 ON g2.ID=pog2.GAME_ID)) AS tmp;
Query may have typos. First selects Particpants in a game, or in no game, but it's excluding the participants only in final games. The second select fills those back in, ignoring the game.
Also:
To select all participants, and not just 'home' participants, not in a game or in a non-playoff game, add OR p.ID=g.AWAY_PARTICIPANT_ID to the ON clause. (I'm following your example, but the description seems to be at odds.
Should there be a foreign key constraint on PLAY_OFF_GAME? E.g., CONSTRAINT play_off_game_fk FOREIGN KEY (GAME_ID) REFERENCES GAME (ID)?

SQLite3 INNER JOIN with 3 tables

I'm trying to select from 3 tables with an INNER JOIN:
The tables:
CREATE TABLE tracks (
'track_id' INTEGER PRIMARY KEY NOT NULL,
'name' TEXT NOT NULL,
'length' REAL DEFAULT '0.00',
'city' TEXT
);
CREATE TABLE heats (
'heat_id' INTEGER PRIMARY KEY NOT NULL,
'track_id' INTEGER UNSIGNED NOT NULL,
'heat_pos' INTEGER UNSIGNED NOT NULL,
'day_pos' INTEGER UNSIGNED NOT NULL,
'type' TEXT NOT NULL DEFAULT 'training',
'average' REAL,
'date' TEXT,
'comment' TEXT,
FOREIGN KEY ('track_id') REFERENCES tracks ('track_id')
);
CREATE TABLE laps (
'lap_id' INTEGER PRIMARY KEY NOT NULL,
'heat_id' INTEGER UNSIGNED NOT NULL,
'laptime' REAL UNSIGNED NOT NULL,
FOREIGN KEY ('heat_id') REFERENCES heats ('heat_id')
);
When selecting information from 2 tables (laps and heats) it works like I expected:
select
laps.lap_id,
laps.laptime,
heats.heat_pos
from laps
inner join heats on laps.heat_id = heats.heat_id;
But now I want to select the corresponding tracknames from the track table:
select
laps.lap_id,
laps.laptime,
heats.heat_pos,
tracks.name
from laps, tracks, heats
inner join heats on laps.heat_id = heats.heat_id and
inner join heats on tracks.track_id = heats.track_id;
This gives me the following error:
ambiguous column name: heats.heat_pos
I'm completely lost, but I have a feeling it's just a small mistake.
Anyone knows what I'm doing wrong?
select
laps.lap_id,
laps.laptime,
heats.heat_pos,
tracks.name
from laps
inner join heats on laps.heat_id = heats.heat_id
inner join tracks on tracks.track_id = heats.track_id;
select
laps.lap_id,
laps.laptime,
heats.heat_pos,
tracks.name
from laps
inner join heats on laps.heat_id = heats.heat_id
inner join heats on tracks.track_id = heats.track_id
ORDER BY laps.lap_id