Sie sind auf Seite 1von 18

/**************************************************************

SUBQUERIES IN THE FROM AND SELECT CLAUSES


Works for MySQL and Postgres
SQLite doesn't support All
**************************************************************/
/**************************************************************
Students whose scaled GPA changes GPA by more than 1
**************************************************************/
select sID, sName, GPA, GPA*(sizeHS/1000.0) as scaledGPA
from Student
where GPA*(sizeHS/1000.0) - GPA > 1.0
or GPA - GPA*(sizeHS/1000.0) > 1.0;
/*** Can simplify using absolute value function ***/
select sID, sName, GPA, GPA*(sizeHS/1000.0) as scaledGPA
from Student
where abs(GPA*(sizeHS/1000.0) - GPA) > 1.0;
/*** Can further simplify using subquery in From ***/
select *
from (select sID, sName, GPA, GPA*(sizeHS/1000.0) as scaledGPA
from Student) G
where abs(scaledGPA - GPA) > 1.0;
/**************************************************************
Colleges paired with the highest GPA of their applicants
**************************************************************/
select College.cName, state, GPA
from College, Apply, Student
where College.cName = Apply.cName
and Apply.sID = Student.sID
and GPA >= all
(select GPA from Student, Apply
where Student.sID = Apply.sID
and Apply.cName = College.cName);
/*** Add Distinct to remove duplicates ***/
select distinct College.cName, state, GPA
from College, Apply, Student
where College.cName = Apply.cName
and Apply.sID = Student.sID
and GPA >= all
(select GPA from Student, Apply
where Student.sID = Apply.sID
and Apply.cName = College.cName);

/*** Use subquery in Select ***/


select distinct cName, state,
(select distinct GPA
from Apply, Student
where College.cName = Apply.cName
and Apply.sID = Student.sID
and GPA >= all
(select GPA from Student, Apply
where Student.sID = Apply.sID
and Apply.cName = College.cName)) as GPA
from College;
/*** Now pair colleges with names of their applicants
(doesn't work due to multiple rows in subquery result) ***/
select distinct cName, state,
(select distinct sName
from Apply, Student
where College.cName = Apply.cName
and Apply.sID = Student.sID) as sName
from College;

/**************************************************************
SUBQUERIES IN THE WHERE CLAUSE
Works for MySQL, Postgres
SQLite doesn't support All or Any
**************************************************************/
/**************************************************************
IDs and names of students applying to CS
**************************************************************/
select sID, sName
from Student
where sID in (select sID from Apply where major = 'CS');
/**************************************************************
Same query written without 'In'
**************************************************************/
select sID, sName
from Student, Apply
where Student.sID = Apply.sID and major = 'CS';
/*** Fix error ***/
select Student.sID, sName
from Student, Apply

where Student.sID = Apply.sID and major = 'CS';


/*** Remove duplicates ***/
select distinct Student.sID, sName
from Student, Apply
where Student.sID = Apply.sID and major = 'CS';
/**************************************************************
Just names of students applying to CS
**************************************************************/
select sName
from Student
where sID in (select sID from Apply where major = 'CS');
/**************************************************************
Same query written without 'In'
**************************************************************/
select sName
from Student, Apply
where Student.sID = Apply.sID and major = 'CS';
/*** Remove duplicates (still incorrect) ***/
select distinct sName
from Student, Apply
where Student.sID = Apply.sID and major = 'CS';
/**************************************************************
Duplicates are important: average GPA of CS applicants
**************************************************************/
select GPA
from Student
where sID in (select sID from Apply where major = 'CS');
/**************************************************************
Alternative (incorrect) queries without 'In'
**************************************************************/
select GPA
from Student, Apply
where Student.sID = Apply.sID and major = 'CS';
select distinct GPA
from Student, Apply
where Student.sID = Apply.sID and major = 'CS';
/**************************************************************
Students who applied to CS but not EE

(query we used 'Except' for earlier)


**************************************************************/
select sID, sName
from Student
where sID in (select sID from Apply where major = 'CS')
and sID not in (select sID from Apply where major = 'EE');
/*** Change to 'not sID in' ***/
select sID, sName
from Student
where sID in (select sID from Apply where major = 'CS')
and not sID in (select sID from Apply where major = 'EE');
/**************************************************************
Colleges such that some other college is in the same state
**************************************************************/
select cName, state
from College C1
where exists (select * from College C2
where C2.state = C1.state);
/*** Fix error ***/
select cName, state
from College C1
where exists (select * from College C2
where C2.state = C1.state and C2.cName <> C1.cName);
/**************************************************************
Biggest college
**************************************************************/
select cName
from College C1
where not exists (select * from College C2
where C2.enrollment > C1.enrollment);
/*** Similar: student with highest GPA ***/
select sName
from Student C1
where not exists (select * from Student C2
where C2.GPA > C1.GPA);
/*** Add GPA ***/
select sName, GPA
from Student C1
where not exists (select * from Student C2

where C2.GPA > C1.GPA);


/**************************************************************
Highest GPA with no subquery
**************************************************************/
select S1.sName, S1.GPA
from Student S1, Student S2
where S1.GPA > S2.GPA;
/*** Remove duplicates (still incorrect) ***/
select distinct S1.sName, S1.GPA
from Student S1, Student S2
where S1.GPA > S2.GPA;
/**************************************************************
Highest GPA using ">= all"
**************************************************************/
select sName, GPA
from Student
where GPA >= all (select GPA from Student);
/**************************************************************
Higher GPA than all other students
**************************************************************/
select sName, GPA
from Student S1
where GPA > all (select GPA from Student S2
where S2.sID <> S1.sID);
/*** Similar: higher enrollment than all other colleges ***/
select cName
from College S1
where enrollment > all (select enrollment from College S2
where S2.cName <> S1.cName);
/*** Same query using 'Not <= Any' ***/
select cName
from College S1
where not enrollment <= any (select enrollment from College S2
where S2.cName <> S1.cName);
/**************************************************************
Students not from the smallest HS
**************************************************************/
select sID, sName, sizeHS

from Student
where sizeHS > any (select sizeHS from Student);
/**************************************************************
Students not from the smallest HS
Some systems don't support Any/All
**************************************************************/
select sID, sName, sizeHS
from Student S1
where exists (select * from Student S2
where S2.sizeHS < S1.sizeHS);
/**************************************************************
Students who applied to CS but not EE
**************************************************************/
select sID, sName
from Student
where sID = any (select sID from Apply where major = 'CS')
and sID <> any (select sID from Apply where major = 'EE');
/*** Subtle error, fix ***/
select sID, sName
from Student
where sID = any (select sID from Apply where major = 'CS')
and not sID = any (select sID from Apply where major = 'EE');

/**************************************************************
JOIN OPERATORS
Works for Postgres
MySQL doesn't support FULL OUTER JOIN
SQLite doesn't support RIGHT or FULL OUTER JOIN
**************************************************************/
/**************************************************************
INNER JOIN
Student names and majors for which they've applied
**************************************************************/
select distinct sName, major
from Student, Apply
where Student.sID = Apply.sID;
/*** Rewrite using INNER JOIN ***/
select distinct sName, major
from Student inner join Apply

on Student.sID = Apply.sID;
/*** Abbreviation is JOIN ***/
select distinct sName, major
from Student join Apply
on Student.sID = Apply.sID;
/**************************************************************
INNER JOIN WITH ADDITIONAL CONDITIONS
Names and GPAs of students with sizeHS < 1000 applying to
CS at Stanford
**************************************************************/
select sName, GPA
from Student, Apply
where Student.sID = Apply.sID
and sizeHS < 1000 and major = 'CS' and cName = 'Stanford';
/*** Rewrite using JOIN ***/
select sName, GPA
from Student join Apply
on Student.sID = Apply.sID
where sizeHS < 1000 and major = 'CS' and cName = 'Stanford';
/*** Can move everything into JOIN ON condition ***/
select sName, GPA
from Student join Apply
on Student.sID = Apply.sID
and sizeHS < 1000 and major = 'CS' and cName = 'Stanford';
/**************************************************************
THREE-WAY INNER JOIN
Application info: ID, name, GPA, college name, enrollment
**************************************************************/
select Apply.sID, sName, GPA, Apply.cName, enrollment
from Apply, Student, College
where Apply.sID = Student.sID and Apply.cName = College.cName;
/*** Rewrite using three-way JOIN ***/
/*** Works in SQLite and MySQL but not Postgres ***/
select Apply.sID, sName, GPA, Apply.cName, enrollment
from Apply join Student join College
on Apply.sID = Student.sID and Apply.cName = College.cName;
/*** Rewrite using binary JOIN ***/
select Apply.sID, sName, GPA, Apply.cName, enrollment

from (Apply join Student on Apply.sID = Student.sID) join College on Apply.cName =


College.cName;
/**************************************************************
NATURAL JOIN
Student names and majors for which they've applied
**************************************************************/
select distinct sName, major
from Student inner join Apply
on Student.sID = Apply.sID;
/*** Rewrite using NATURAL JOIN ***/
select distinct sName, major
from Student natural join Apply;
/*** Like relational algebra, eliminates duplicate columns ***/
select *
from Student natural join Apply;
select distinct sID
from Student natural join Apply;
/*** Would get ambiguity error with cross-product ***/
select distinct sID
from Student, Apply;
/**************************************************************
NATURAL JOIN WITH ADDITIONAL CONDITIONS
Names and GPAs of students with sizeHS < 1000 applying to
CS at Stanford
**************************************************************/
select sName, GPA
from Student join Apply
on Student.sID = Apply.sID
where sizeHS < 1000 and major = 'CS' and cName = 'Stanford';
/*** Rewrite using NATURAL JOIN ***/
select sName, GPA
from Student natural join Apply
where sizeHS < 1000 and major = 'CS' and cName = 'Stanford';
/*** USING clause considered safer ***/
select sName, GPA
from Student join Apply using(sID)
where sizeHS < 1000 and major = 'CS' and cName = 'Stanford';

/**************************************************************
SELF-JOIN
Pairs of students with same GPA
**************************************************************/
select S1.sID, S1.sName, S1.GPA, S2.sID, S2.sName, S2.GPA
from Student S1, Student S2
where S1.GPA = S2.GPA and S1.sID < S2.sID;
/*** Rewrite using JOIN and USING (disallowed) ***/
select S1.sID, S1.sName, S1.GPA, S2.sID, S2.sName, S2.GPA
from Student S1 join Student S2 on S1.sID < S2.sID using(GPA);
/*** Without ON clause ***/
select S1.sID, S1.sName, S1.GPA, S2.sID, S2.sName, S2.GPA
from Student S1 join Student S2 using(GPA)
where S1.sID < S2.sID;
/**************************************************************
SELF NATURAL JOIN
**************************************************************/
select *
from Student S1 natural join Student S2;
/*** Verify equivalence to Student ***/
select * from Student;
/**************************************************************
LEFT OUTER JOIN
Student application info: name, ID, college name, major
**************************************************************/
select sName, sID, cName, major
from Student inner join Apply using(sID);
/*** Include students who haven't applied anywhere ***/
select sName, sID, cName, major
from Student left outer join Apply using(sID);
/*** Abbreviation is LEFT JOIN ***/
select sName, sID, cName, major
from Student left join Apply using(sID);
/*** Using NATURAL OUTER JOIN ***/

select sName, sID, cName, major


from Student natural left outer join Apply;
/*** Can simulate without any JOIN operators ***/
select sName, Student.sID, cName, major
from Student, Apply
where Student.sID = Apply.sID
union
select sName, sID, NULL, NULL
from Student
where sID not in (select sID from Apply);
/*** Instead include applications without matching students ***/
insert into Apply values (321, 'MIT', 'history', 'N');
insert into Apply values (321, 'MIT', 'psychology', 'Y');
select sName, sID, cName, major
from Apply natural left outer join Student;
/**************************************************************
RIGHT OUTER JOIN
Student application info: name, ID, college name, major
**************************************************************/
/*** Include applications without matching students ***/
select sName, sID, cName, major
from Student natural right outer join Apply;
/**************************************************************
FULL OUTER JOIN
Student application info
**************************************************************/
/*** Include students who haven't applied anywhere ***/
/*** and applications without matching students ***/
select sName, sID, cName, major
from Student full outer join Apply using(sID);
/*** Can simulate with LEFT and RIGHT outerjoins ***/
/*** Note UNION eliminates duplicates ***/
select sName, sID, cName, major
from Student left outer join Apply using(sID)
union
select sName, sID, cName, major
from Student right outer join Apply using(sID);
/*** Can simulate without any JOIN operators ***/

select sName, Student.sID, cName, major


from Student, Apply
where Student.sID = Apply.sID
union
select sName, sID, NULL, NULL
from Student
where sID not in (select sID from Apply)
union
select NULL, sID, cName, major
from Apply
where sID not in (select sID from Student);
/**************************************************************
THREE-WAY OUTER JOIN
Not associative
**************************************************************/
create table T1 (A int, B int);
create table T2 (B int, C int);
create table T3 (A int, C int);
insert into T1 values (1,2);
insert into T2 values (2,3);
insert into T3 values (4,5);
select A,B,C
from (T1 natural full outer join T2) natural full outer join T3;
select A,B,C
from T1 natural full outer join (T2 natural full outer join T3);
drop table T1;
drop table T2;
drop table T3;

/**************************************************************
AGGREGATION
Works for SQLite, MySQL
Postgres doesn't allow ambiguous Select columns in Group-by queries
**************************************************************/
/**************************************************************
Average GPA of all students
**************************************************************/
select avg(GPA)
from Student;
/**************************************************************

Lowest GPA of students applying to CS


**************************************************************/
select min(GPA)
from Student, Apply
where Student.sID = Apply.sID and major = 'CS';
/*** Average GPA of students applying to CS ***/
select avg(GPA)
from Student, Apply
where Student.sID = Apply.sID and major = 'CS';
/*** Fix incorrect counting of GPAs ***/
select avg(GPA)
from Student
where sID in (select sID from Apply where major = 'CS');
/**************************************************************
Number of colleges bigger than 15,000
**************************************************************/
select count(*)
from College
where enrollment > 15000;
/**************************************************************
Number of students applying to Cornell
**************************************************************/
select count(*)
from Apply
where cName = 'Cornell';
/*** Show why incorrect result, fix using Count Distinct ***/
select *
from Apply
where cName = 'Cornell';
select Count(Distinct sID)
from Apply
where cName = 'Cornell';
/**************************************************************
Students such that number of other students with same GPA is
equal to number of other students with same sizeHS
**************************************************************/
select *
from Student S1

where (select count(*) from Student S2


where S2.sID <> S1.sID and S2.GPA = S1.GPA) =
(select count(*) from Student S2
where S2.sID <> S1.sID and S2.sizeHS = S1.sizeHS);
/**************************************************************
Amount by which average GPA of students applying to CS
exceeds average of students not applying to CS
**************************************************************/
select CS.avgGPA - NonCS.avgGPA
from (select avg(GPA) as avgGPA from Student
where sID in (
select sID from Apply where major = 'CS')) as CS,
(select avg(GPA) as avgGPA from Student
where sID not in (
select sID from Apply where major = 'CS')) as NonCS;
/*** Same using subqueries in Select ***/
select (select avg(GPA) as avgGPA from Student
where sID in (
select sID from Apply where major = 'CS')) (select avg(GPA) as avgGPA from Student
where sID not in (
select sID from Apply where major = 'CS')) as d
from Student;
/*** Remove duplicates ***/
select distinct (select avg(GPA) as avgGPA from Student
where sID in (
select sID from Apply where major = 'CS')) (select avg(GPA) as avgGPA from Student
where sID not in (
select sID from Apply where major = 'CS')) as d
from Student;
/**************************************************************
Number of applications to each college
**************************************************************/
select cName, count(*)
from Apply
group by cName;
/*** First do query to picture grouping ***/
select *
from Apply
order by cName;

/*** Now back to query we want ***/


select cName, count(*)
from Apply
group by cName;
/**************************************************************
College enrollments by state
**************************************************************/
select state, sum(enrollment)
from College
group by state;
/**************************************************************
Minimum + maximum GPAs of applicants to each college & major
**************************************************************/
select cName, major, min(GPA), max(GPA)
from Student, Apply
where Student.sID = Apply.sID
group by cName, major;
/*** First do query to picture grouping ***/
select cName, major, GPA
from Student, Apply
where Student.sID = Apply.sID
order by cName, major;
/*** Now back to query we want ***/
select cName, major, min(GPA), max(GPA)
from Student, Apply
where Student.sID = Apply.sID
group by cName, major;
/*** Widest spread ***/
select max(mx-mn)
from (select cName, major, min(GPA) as mn, max(GPA) as mx
from Student, Apply
where Student.sID = Apply.sID
group by cName, major) M;
/**************************************************************
Number of colleges applied to by each student
**************************************************************/
select Student.sID, count(distinct cName)
from Student, Apply
where Student.sID = Apply.sID

group by Student.sID;
/*** First do query to picture grouping ***/
select Student.sID, cName
from Student, Apply
where Student.sID = Apply.sID
order by Student.sID;
/*** Now back to query we want ***/
select Student.sID, count(distinct cName)
from Student, Apply
where Student.sID = Apply.sID
group by Student.sID;
/*** Add student name ***/
select Student.sID, sName, count(distinct cName)
from Student, Apply
where Student.sID = Apply.sID
group by Student.sID;
/*** First do query to picture grouping ***/
select Student.sID, sName, cName
from Student, Apply
where Student.sID = Apply.sID
order by Student.sID;
/*** Now back to query we want ***/
select Student.sID, sName, count(distinct cName)
from Student, Apply
where Student.sID = Apply.sID
group by Student.sID;
/*** Add college (shouldn't work but does in some systems) ***/
select Student.sID, sName, count(distinct cName), cName
from Student, Apply
where Student.sID = Apply.sID
group by Student.sID;
/*** Back to query to picture grouping ***/
select Student.sID, sName, cName
from Student, Apply
where Student.sID = Apply.sID
order by Student.sID;
/**************************************************************

Number of colleges applied to by each student, including


0 for those who applied nowhere
**************************************************************/
select Student.sID, count(distinct cName)
from Student, Apply
where Student.sID = Apply.sID
group by Student.sID;
/*** Now add 0 counts ***/
select Student.sID, count(distinct cName)
from Student, Apply
where Student.sID = Apply.sID
group by Student.sID
union
select sID, 0
from Student
where sID not in (select sID from Apply);
/**************************************************************
Colleges with fewer than 5 applications
**************************************************************/
select cName
from Apply
group by cName
having count(*) < 5;
/*** Same query without Group-by or Having ***/
select cName
from Apply A1
where 5 > (select count(*) from Apply A2 where A2.cName = A1.cName);
/*** Remove duplicates ***/
select distinct cName
from Apply A1
where 5 > (select count(*) from Apply A2 where A2.cName = A1.cName);
/*** Back to original Group-by form, fewer than 5 applicants ***/
select cName
from Apply
group by cName
having count(distinct sID) < 5;
/**************************************************************
Majors whose applicant's maximum GPA is below the average
**************************************************************/

select major
from Student, Apply
where Student.sID = Apply.sID
group by major
having max(GPA) < (select avg(GPA) from Student);

/**************************************************************
NULL VALUES
Works for SQLite, MySQL, Postgres
**************************************************************/
insert into Student values (432, 'Kevin', null, 1500);
insert into Student values (321, 'Lori', null, 2500);
select * from Student;
/**************************************************************
All students with high GPA
**************************************************************/
select sID, sName, GPA
from Student
where GPA > 3.5;
/*** Now low GPA ***/
select sID, sName, GPA
from Student
where GPA <= 3.5;
/*** Now either high or low GPA ***/
select sID, sName, GPA
from Student
where GPA > 3.5 or GPA <= 3.5;
/*** Now all students ***/
select sID, sName from Student;
/*** Now use 'is null' ***/
select sID, sName, GPA
from Student
where GPA > 3.5 or GPA <= 3.5 or GPA is null;
/**************************************************************
All students with high GPA or small HS
**************************************************************/

select sID, sName, GPA, sizeHS


from Student
where GPA > 3.5 or sizeHS < 1600;
/*** Add large HS ***/
select sID, sName, GPA, sizeHS
from Student
where GPA > 3.5 or sizeHS < 1600 or sizeHS >= 1600;
/**************************************************************
Number of students with non-null GPAs
**************************************************************/
select count(*)
from Student
where GPA is not null;
/*** Number of distinct GPA values among them ***/
select count(distinct GPA)
from Student
where GPA is not null;
/*** Drop non-null condition ***/
select count(distinct GPA)
from Student;
/*** Drop count ***/
select distinct GPA
from Student;

Das könnte Ihnen auch gefallen