Using multiple inner joins and sorting result - sql

In my DB there are three tables. I am trying to figure out how to List the school name, class name and teacher's name. Sort the records by class name within school name. I have a query but it is not working. How can I list the school name, class name and teacher's name and sort record by class name within school name?
SELECT c.class_name FROM class c INNER JOIN teacher t WHERE t.teacher_id = c.teacher_id INNER JOIN school s WHERE t.school_id = s.school_id;
TABLES
SQL> select * from class;
CLASS_ID CLASS_NAME TEACHER_ID MAX_SEATS_AVAILABLE
---------- ------------------- ---------- -------------------
1 Intro to ALGEBRA 11 12
2 Basic CALCULUS 2 10
3 ABC and 123 1 15
4 Sharing 101 8 10
5 Good Talk, Bad Talk 9 20
6 Nap Time 1 21
7 WRITing 101 5 10
8 Finger Painting 9 14
9 Physics 230 2 20
10 Gym 5 25
10 rows selected.
SQL> select * from teacher;
TEACHER_ID FIRST_NAME LAST_NAME T HOME_ROOM_NUM PHONE_NUM START_DAT HO SCHOOL_ID
---------- ---------------- ---------------- - ------------- ---------- --------- -- ----------
1 FRanK JOHNSON k 10C 22-OCT-97 In 11090
2 LISA JONES h 11Bc 317-587-90 19-JAN-15 iN 123134
87
3 Jeff Dafferty C W8CZ 12-DEC-96 OH 11546
4 Frank MARTIN g 12aA 212-098-98 19-JAN-15 IN 11090
76
5 John Smith H 34C 10-OCT-93 In 123134
6 John Smith G 34C 10-OCT-93 in 11090
7 Lisa Jones G 11E 317-587-90 19-JAN-15 IN 123134
87
8 Trevor Horse k x 19-JAN-15 Oh 11090
9 Gregor Ivan K 12A 317-987-09 10-NOV-96 KY 11090
87
10 Gregor Ivan g 12A 317-987-09 10-NOV-96 Ky 11090
87
11 Pat Francis H 1z1a 123-317-09 19-JAN-15 Il 11546
12
12 Brad Smith G 13A 18-NOV-94 IN 11546
12 rows selected.
SQL> select * from school;
SCHOOL_ID SCHOOL_NAME SCHOOL_TYPE
---------- ----------------------------- ------------
11546 Ivy Tech College COLLegE
11090 LAWRENCE Central Grade School GRADE SCHOOL
11111 Lawrence NORTH High School HIGH SCHooL
19283 Howe High SCHOOL High SchooL
123134 Lawrence Central High School HIGH SCHOOL
192 Little Big Horn Grade School GRADE SCHOOL

You can use the join to get what you want. This will give the all schools with the teachers and there classes.
SELECT DISTINCT
sc.SCHOOL_NAME,
teach.FIRST_NAME,
teach.LAST_NAME ,
cs.CLASS_NAME
FROM
school sc JOIN teacher teach
ON sc.SCHOOL_ID = teach.SCHOOL_ID
JOIN class cs ON cs.TEACHER_ID = teach.TEACHER_ID
ORDER BY
sc.SCHOOL_NAME,cs.CLASS_NAME

SELECT t.FIRST_NAME +' '+t.LAST_NAME, s.SCHOOL_NAME, c.class_name
FROM class c
INNER JOIN teacher t
ON t.teacher_id = c.teacher_id
INNER JOIN school s
ON t.school_id = s.school_id
ORDER BY s.SCHOOL_NAME,c.CLASS_NAME

Related

SQL Distinct pairs matched on array of strings

This is a simplified version of the tables but I have a table called NAME with 2 columns, names (strings) and classes (strings)
index
name
classes
0
Joe
Mat 12
1
Hector
Mat 12
2
Terry
Arc 13
3
Elizabeth
Soc 7
4
Wyatt
Arc 13
5
Alex
His 9
6
James
Mat 12
7
Rebecca
Soc 7
NOTE: All names and classes actually have a numerical ID associated with them, used actual names for illustration.
I want to pair up unique people taking the same class, with the output table looking something like this.
name1
name2
class
Joe
Hector
Mat 12
Joe
James
Mat 12
Hector
James
Mat 12
Terry
Wyatt
Arc 12
Worth noting is that the output table should have unique pairs and a person shouldn't be paired with themselves (so don't want outcome like this)
name1
name2
class
Joe
Hector
Mat 12
Hector
Joe
Mat 12
Joe
Joe
Mat 12
I've tried something along the lines of
SELECT NAME.names as name1, NAME.names as name2, NAME.classes as c1, COUNT(*) as pa
FROM NAME
JOIN NAME
ON name1.c1 = name2.c1
GROUP BY name1, name2
ORDER BY c1
But doesn't work.
You may achieve this using a join and comparison based on the index/name
Query #1
SELECT
n1.name as name1,
n2.name as name2,
n1.classes
FROM
NAME n1
INNER JOIN
NAME n2 ON n1.classes=n2.classes AND n1.index < n2.index;
name1
classes
name2
Joe
Mat 12
Hector
Terry
Arc 13
Wyatt
Joe
Mat 12
James
Hector
Mat 12
James
Elizabeth
Soc 7
Rebecca
Query #2
SELECT
n1.name as name1,
n2.name as name2,
n1.classes
FROM
NAME n1
INNER JOIN
NAME n2 ON n1.classes=n2.classes AND n1.name < n2.name;
name1
classes
name2
Hector
Mat 12
Joe
James
Mat 12
Joe
Terry
Arc 13
Wyatt
Hector
Mat 12
James
Elizabeth
Soc 7
Rebecca
View on DB Fiddle
Let me know if this works for you.

Selecting from a table that contains ALL of another table

Let's say I have three tables:
Employees:
PID NAME WAGE
---------- -------------------- ----------
10234 Able 8
11567 Baker 9
3289 George 10
88331 Alice 11
Employee_made:
PID SID QUANTITY HOURS
---------- ---------- ---------- ----------
10234 11 24 3
10234 12 6 1
10234 13 24 1
10234 21 6 1
10234 23 4 1
10234 31 48 6
11567 23 4 1
11567 31 1 1
88331 11 6 1
Sandwich:
SID PRICE NAME
---------- ---------- ------------------------------
12 2 hamburger on wheat
13 2 cheese burger
21 1.75 fish burger on rye
23 1.75 fish burger on wheat
31 3 veggie burger on wheat
11 2 hamburger on rye
I need to list all the employees who have made ALL the different sandwiches, and display their names and PID. What I've gotten so far is:
Select E.name, E.pid
From employees E, employee_made EM, sandwich S
Where E.pid = EM.pid
Which tells me the matching PIDs from the employees and employee_made table. Where I'm not sure to go is how to display the employees who have made ALL the sandwiches, so matching not any SID to the employee_made table, but ALL of them.
First, never use commas in the FROM clause. Always use proper, explicit JOIN syntax.
You can approach this by counting the number of sandwiches mades by employees and then comparing to the total count of sandwiches:
select em.pid
from employee_made em
group by em.pid
having count(distinct em.sid) = (select count(*) from sandwich);
This gives the pid of the employee. I'll let you figure out how to bring in the employee name (hint: in, exists, and join could all be used).

sql from row to columns

Please help me out with the following issue. want to convert row data into the columns based on value of "PeriodNum" column max column will up to period8... there are multiple teachers in the table...below is just sample of 2 teachers.
Sample of data:
id teachername course_name periodnum courseid
------------------------------------------------------------------
14088 Smith, John 1; Physical Education 9 GYM ABCD 1 10064
14088 Smith, John 2; Physical Education 9 GYM ABCD 2 10064
14088 Smith, John 3; Physical Education 11 GYM BD 3 10065
14088 Smith, John 5; Physical Education 11 GYM AC 5 10065
14088 Smith, John 6; Physical Education 11 GYM ABCD 6 10065
14088 Smith, John 7; Health 9 P373 ABCD 7 10059
14088 Smith, John 8; Physical Education 11 GYM AC 8 10065
14088 Smith, John 8; Health 10 GYM BD 8 10066
15411 Yong, Jerry 1; Science 6 ABCD 1 10078
15411 Yong, Jerry 2; Science 9 ABCD 2 10078
15411 Yong, Jerry 3; Science 11 BD 3 10078
15411 Yong, Jerry 5; Science 11 AC 5 10078
15411 Yong, Jerry 6; Science 11 ABCD 6 10078
15411 Yong, Jerry 7; Maths P373 ABCD 7 10080
15411 Yong, Jerry 8; Biology 11 AC 8 10041
I want to have desired result to look like following:
id teachername Period1 Period2 Period3 Period4 Period5 Period6 Period7 Period8
14088 Smith, John 1; Physical Education 9 GYM ABCD 2; Physical Education 9 GYM ABCD 3; Physical Education 11 GYM BD NULL 5; Physical Education 11 GYM AC 6; Physical Education 11 GYM ABCD 7; Health 9 P373 ABCD 8; Physical Education 11 GYM AC + 8; Health 10 GYM BD
15411 Yong, Jerry 1; Science 6 ABCD 2; Science 9 ABCD 3; Science 11 BD 5; Science 11 AC 6; Science 11 ABCD 7; Maths P373 ABCD 8; Biology 11 AC
thanks...so much.
I've tried following query
SELECT DISTINCT
t.[id],
t.[teachername]
,t1.course_name AS period1,t2.course_name AS period2,t3.course_name AS period3, t4.course_name AS period4, t5.course_name AS period5, t6.course_name AS period6,
t7.course_name AS period7,t8.course_name AS period8 -- into ccs_test
FROM #teacher t
LEFT OUTER JOIN CompanyGrouped t1 ON t.[id]=t1.[id] AND t1.ColumnNumber=1 and t.periodnum=1
LEFT OUTER JOIN CompanyGrouped t2 ON t.[id]=t2.[id] AND t2.ColumnNumber=2 and t.periodnum=2
LEFT OUTER JOIN CompanyGrouped t3 ON t.[id]=t3.[id] AND t3.ColumnNumber=3 and t.periodnum=3
LEFT OUTER JOIN CompanyGrouped t4 ON t.[id]=t4.[id] AND t4.ColumnNumber=4 and t.periodnum=4
LEFT OUTER JOIN CompanyGrouped t5 ON t.[id]=t5.[id] AND t5.ColumnNumber=5 and t.periodnum=5
LEFT OUTER JOIN CompanyGrouped t6 ON t.[id]=t6.[id] AND t6.ColumnNumber=6 and t.periodnum=6
LEFT OUTER JOIN CompanyGrouped t7 ON t.[id]=t7.[id] AND t7.ColumnNumber=7 and t.periodnum=7
LEFT OUTER JOIN CompanyGrouped t8 ON t.[id]=t8.[id] AND t7.ColumnNumber=8 and t.periodnum=8
Regards,
HT
I brought the data into a table in SQL Server and was able to pivot to the results you were looking for.
SELECT ID
, TeacherName
,[1] as Period1
,[2] as Period2
,[3] as Period3
,[4] as Period4
,[5] as Period5
,[6] as Period6
,[7] as Period7
,[8] as Period8
FROM
(SELECT ID, TeacherName, peridonum, course_name
FROM teacher) src
PIVOT
(MAX(course_name) FOR peridonum in ([1],[2],[3],[4],[5],[6],[7],[8])
) pvt

SQL Select Distinct returning duplicates

I am trying to return the country, golfer name, golfer age, and average drive for the golfers with the highest average drive from each country.
However I am getting a result set with duplicates of the same country. What am I doing wrong? here is my code:
select distinct country, name, age, avgdrive
from pga.golfers S1
inner join
(select max(avgdrive) as MaxDrive
from pga.golfers
group by country) S2
on S1.avgdrive = s2.MaxDrive
order by avgdrive;
These are some of the results I've been getting back, I should only be getting 15 rows, but instead I'm getting 20:
COUN NAME AGE AVGDRIVE
---- ------------------------------ ---------- ----------
Can Mike Weir 35 279.9
T&T Stephen Ames 41 285.8
USA Tim Petrovic 39 285.8
Ger Bernhard Langer 47 289.3
Swe Fredrik Jacobson 30 290
Jpn Ryuji Imada 28 290
Kor K.J. Choi 37 290.4
Eng Greg Owen 33 291.8
Ire Padraig Harrington 33 291.8
USA Scott McCarron 40 291.8
Eng Justin Rose 25 293.1
Ind Arjun Atwal 32 293.7
USA John Rollins 30 293.7
NIr Darren Clarke 37 294
Swe Daniel Chopra 31 297.2
Aus Adam Scott 25 300.6
Fij Vijay Singh 42 300.7
Spn Sergio Garcia 25 301.9
SAf Ernie Els 35 302.9
USA Tiger Woods 29 315.2
You are missing a join condition:
select s1.country, s1.name, s1.age, s1.avgdrive
from pga.golfers S1 inner join
(select country, max(avgdrive) as MaxDrive
from pga.golfers
group by country
) S2
on S1.avgdrive = s2.MaxDrive and s1.country = s2.country
order by s1.avgdrive;
Your problem is that some people in one country have the same average as the best in another country.
DISTINCT eliminated duplicate rows, not values in some fields.
To get a list of countries with ages, names, and max drives, you would need to group the whole select by country.

Why does my view query split into two?

I am trying to create a view that records the selected attributes for all Computer Science majors.
This is my query to create a view:
DROP VIEW CS_grade_report;
CREATE VIEW CS_grade_report AS
SELECT Student.student_id AS "ID",
student_name AS "Name",
course_number AS "Course #",
credit AS "Credit",
grade AS Grade
FROM Student, Class, Enrolls
WHERE major = 'CSCI'
AND Student.student_id = Enrolls.student_id
AND Class.schedule_num = Enrolls.schedule_num;
SELECT *
FROM CS_grade_report;
And this is what is generated:
ID Name Course # Credit GR
------ ------------------------- -------- ---------- --
600000 John Smith CSCI3200 4 B+
600000 John Smith CSCI3700 3 C
600000 John Smith SPAN1004 3 A-
600000 John Smith CSCI4300 3 A+
600001 Andrew Tram MUSC2406 2 A+
600001 Andrew Tram SPAN1004 3 A
600001 Andrew Tram CSCI3700 3 B-
600002 Jane Doe CSCI4200 3 D+
600003 Michael Jordan CSCI4300 3 A+
600004 Tiger Woods MUSC1000 1 A
600007 Dominique Davis CSCI4300 3 F
ID Name Course # Credit GR
------ ------------------------- -------- ---------- --
600009 Will Smith CSCI3200 4 A
600010 Papa Johns CSCI3200 4 B
600011 John Doe CSCI3200 4 C
600012 Jackie Chan CSCI3200 4 D
600013 Some Guy CSCI3200 4 E
16 rows selected.
I am assuming this is output from sqlplus. There is a "pagesize" option to define when breaks are added. If you only want to see one heading, set the size to a large enough value prior to running your SELECT statement as such:
set pagesize 500
(or whatever size you want)
There are many command options for sqlplus. This link is a good cheat-sheet.