Writing query in SQL in a different way - sql

I am trying to write a query for this question.
Find the IDs of all students who were taught by an instructor named
Einstein; make sure there are no duplicates in the result.
One suitable answer to this would be
select distinct student.ID
from (student join takes using(ID))
join (instructor join teaches using(ID))
using (course_id, sec_id, semester, year)
where instructor.name = 'Einstein'
but I don't want to use the join.....using Syntax. I want to write the same query without using join....using. I was able to write some parts of the query, but don't understand how to write the whole query without it returning any errors. Below is what I am trying to do, As an alternative to the join....using syntax the query I am trying to write is by enumerating relations in the from clause, and adding the corresponding join predicates on ID, course id, section id, semester, and year to the where clause. But when I do that, its giving me back errors, saying that "no such column exists"
select distinct student.id
from student, takes
where student.id = takes.id
and student.sec_id = takes.sec_id
and student.semester = takes.semester
and student.year = takes.year
How can I fix the code?
Table setup:
Student
ID NAME DEPT_NAME TOT_CRED
-------------------------------------
00128 Zhang Comp. Sci. 102
12345 Shankar Comp. Sci. 32
19991 Brandt History 80
44553 Peltier Physics 56
Instructor
ID NAME DEPT_NAME SALARY
---------------------------------------
10101 Srinivasan Comp. Sci. 65000
12121 Wu Finance 90000
15151 Mozart Music 40000
22222 Einstein Physics 95000
Teaches
ID COURSE_ID SEC_ID SEMESTER YEAR
------------------------------------------
10101 CS-101 1 Fall 2009
10101 CS-315 1 Spring 2010
10101 CS-347 1 Fall 2009
22222 PHY-101 1 Fall 2017
Takes
ID COURSE_ID SEC_ID SEMESTER YEAR GRADE
------------------------------------------------
00128 CS-101 1 Fall 2009 A
00128 CS-347 1 Fall 2009 A-
12345 CS-101 1 Fall 2009 C
44553 PHY-101 1 Fall 2017 B-

Related

Access SQL to capture all related relatives

I have two Access tables, one regarding persons and the other regarding relatives. The tables relation looks like this.
tbl_Person
PersonID
Name
Age
1001
Abraham
12
1002
Bill
13
1003
Catty
14
1004
Derby
15
tbl_Relative
RelativeID
Name
Age
2001
Zack
42
2002
Yan
43
2003
Xavier
44
tbl_Relation
RelationID
PersonID
RelativeID
Relation
9999
2001
1001
Father
9998
2002
1002
Aunt
9997
2003
1003
Uncle
9996
2001
1004
Father
I would like to select a relative (or person) and have an SQL query find persons (or relatives).
E.g. If I select Yan (2002), the SQL query will discover Bill as the Person related to Yan.
Alternatively if I select Derby (1004), the query will discover Zack as the relative, as well as Abraham, who is also related to Zack.
In essence:
Search : Derby, query finds Zack (father) and Abraham
Search : Yan, query finds only Bill
I can join (union) the two tables to form a combined table, like
Select PersonID, Name, Age, "Person" as category From tbl_Person
UNION
Select RelativeID, Name, Age, "Relative" as category From tbl_Relative

Populating A Many-To-Many Table

I have two tables, The Instructor table, and the Department Table. The Instructor can be involved in many departments and the departments can contain many Instructors. I'm trying to populate the DepartmentInstructor table to create a many-to-many relationship. The tables are populated like so,
Department Table
DepartmentID DepartmentName
1 Aaron Copland School of Music
2 American Studies
3 Art
4 Classical, Middle Eastern, and Asian Languages and Cultures
5 Comparative Literature
6 Drama, Theatre & Dance
7 English
8 European Languages and Literatures
Instructor Table
InstructorID InstructorFullName
1 Abrams, Brian
2 Ciavarella, Peter
3 Franklin, Arnold
4 Shur, Mitchell
5 Reich, Toby
6 Meyers, Allison
7 Dana, Kathryn
8 Rhindress, Mindy
What I'm trying to do is,
DepartmentInstructor Table
DepartmentID InstructorID
1 3
3 7
2 7
6 4
Edit:
Responding to #GeorgeJoseph, We were also given a table that contains all of the data besides the IDs. This table is shown below,
Table X
Semester Sec Code Course(HR,CRD) Description Day Time Instructor Location Enrolled Limit ModeOfInstruction
Spring 2019 02 37366 ACCT 100 (3, 3) Fin & Mgr Acct T, TH 3:10 PM - 4:25 PM Milo, Michael KY 419 20 22 In-Person
Spring 2019 03 37823 ACCT 100 (3, 3) Fin & Mgr Acct M 3:10 PM - 6:00 PM Ho, Vivian HH 17 21 22 In-Person
Spring 2019 01 37365 ACCT 100 (3, 3) Fin & Mgr Acct T, TH 10:45 AM - 12:00 PM Milo, Michael KY 419 22 22 In-Person
Spring 2019 06 7351 ACCT 101 (4, 3) Int Theo & Prac Acct 1 T, TH 12:10 PM - 2:00 PM Feisullin, Anita RA 201 30 30 In-Person
Spring 2019 12 7357 ACCT 101 (4, 3) Int Theo & Prac Acct 1 SU 8:20 AM - 12:00 PM Mintz, Chana PH 204 39 55 In-Person
Spring 2019 11 7356 ACCT 101 (4, 3) Int Theo & Prac Acct 1 S 8:20 AM - 12:00 PM Chan, Joseph PH 110 54 55 In-Person
Spring 2019 10 7355 ACCT 101 (4, 3) Int Theo & Prac Acct 1 F 6:30 PM - 10:30 PM Solarsh, Eva PH 212 30 30 Hybrid
Spring 2019 09 7354 ACCT 101 (4, 3) Int Theo & Prac Acct 1 T, TH 8:50 PM - 10:30 PM Zapf, Michael PH 110 29 55 In-Person
I added the data to the Instructor Table and the Department table through this table. Let's call this table X. The DepartmentName was created by using a case statement over the Course(HR,CRD) column.
Now to answer your question, Table X should help us in forming that many-to-many relationship between the Instructor and the Department Table. I'm currently not sure how to map the relationship. What I tried doing was this,
SELECT DISTINCT [Description], Instructor
FROM Schema.X AS x
INNER JOIN [College].[Instructor] AS I
ON x.Instructor = I.InstructorFullName
This will then give me the corresponding course taught by a professor but I'm unsure of how to go from here.
Edit 2:
Here's how my DB design looks,
As George and yourself have mentioned, you are almost there. I am using SQL Server / T-SQL
In my example you have a course table, an instructor table and a department table.
The course table must have the instructorID and the departmentID as a column. This is how you bridge the gap between all the tables. It means that you have a distinct list of departments, courses (with the linking department and tutor IDs) and a distinct list of tutors. There are considerations where a course has more than one tutor (Could happen I suppose) but test out what suits your setup. Probably add a new row to courses with the same departmentId and the 2nd tutorID.
I have added some extra columns in the output.
You can also see not all departments have courses assigned to them. Lack of funding! Also note I have used left join where inner might work better depending on your situation or where clause. EG Where courseID is not null.
http://sqlfiddle.com/#!18/cf48b/1/0
Ok so, through some trial and error and thoroughly reading through the data. I've come to a solution that I believe to be correct,
INSERT INTO [College].[DepartmentInstructor]
(DepartmentInstructorID, DepartmentKey, InstructorKey)
SELECT
NEXT VALUE FOR [Project3].[SequenceObjectForDepartmentInstructorId],
DepartmentID,
InstructorID
FROM (
SELECT DISTINCT InstructorID, DepartmentID
FROM Uploadfile.CoursesSpring2019 AS CS
INNER JOIN [College].[Instructor] AS I
ON CS.Instructor = I.InstructorFullName
INNER JOIN [College].[Department] AS D
ON CS.[Course (hr, crd)] LIKE CONCAT('%', D.DepartmentName, '%')
) AS Result
I've been able to progress further in my project and I'm about 95% done. I've actually stumbled onto a somewhat similar problem. If you refer back to the database design that I posted, the courses table will need the IDs from multiple tables. This is what I've come up with,
SELECT DISTINCT
TS.TimeSlotID,
I.InstructorID,
BL.BuildingLocationID,
C.CourseID
FROM Uploadfile.CoursesSpring2019 AS CS
INNER JOIN [College].[TimeSlot] AS TS
ON CS.[Time] = TS.[ClassHours]
INNER JOIN [College].[Instructor] AS I
ON CS.[Instructor] = I.[InstructorFullName]
INNER JOIN [College].[BuildingLocation] AS BL
ON CS.[Location] LIKE CONCAT( BL.[BuildingName], '%')
INNER JOIN [College].[Course] AS C
ON CS.[Course (hr, crd)] LIKE CONCAT(C.CourseName, '%')
The problem here is that this query results in approximately 1mil rows. Table X has approximately 4700 rows which means that this query that I currently have is nowhere near the number of rows I should have since.

Joining Count and select query

Table Genre
GENRE_CATEGORY DESCRIPTION
-------------- ----------------------
C100 Information Technology
C200 Novel
C300 Cookery
C400 Lifestyle
Table Book
ISBN TITLE PAGE_NUMBER PUBLICATION_YEAR PUBLISHER_CODE GENRE_CATEGORY
------------ ----------------- ----------- ---------------- -------------- --------------
123-0-12-374 Rainbow Mountain 200 2011 P2001 C200
989-2-96-545 Data Mining 340 2012 P2002 C100
718-8-16-555 Asian Food 280 2013 P3002 C300
674-9-90-345 Yoga for the mind 180 2016 P2002 C400
900-0-88-767 Finding Rainbow 250 2016 P2001 C200
888-9-55-447 Pastry Heaven 200 2016 P3002 C300
what sql statement do i need to write to produce a table with publisher code, description, Number of books(count number of books using count).
The table must show how many number of books for novel , Information technology,lifestyle and cookery. I've spent two hours trying to figure out what to do please do help me
select Publisher_Code,Description, count(genre_category)
from genre
INNER Join book
ON genre.genre_category=book.genre_category
where(genre.genre_category=book.genre_category);
The output must look like this
I think this is what you are looking for...
select Publisher_Code, Description, count(*)
from genre
INNER Join book
ON genre.genre_category=book.genre_category
GROUP BY Publisher_Code, Description;

How to get the student academic progress?

course Table
course_code course_name credit_points_reqd
1 Comp Science 300
2 Soft Engineering 300
subject Table
subject_code subject_name credit_points
CS123 C Prog 15
CS124 COBOL 15
enrolment table
student_id student_name course_code subject_code Results
1 Lara Croft 1 CS123 70
1 Lara Croft 1 CS124 50
2 Tom Raider 2 CS123 60
2 Tom Raider 2 CS124 40
3 James Bond 1 CS123 NULL
3 James Bond 1 CS124 40
OUTPUT TABLE
student_name course_name credit_points_obt credit_points_reqd
Lara Croft Comp Science 30 300
Tom Raider Soft Engineering 15 300
I'm currently using TSQL. So here's the situation. I've prepared these tables to get the output like the way it i showed u up there. I need to calculate the credit points obtained. Credit points are achieved if the student receives > 50 for a subject they took. I want to ignore students that has not received any credit points at all (eg, James Bond is ignored as he has not achieved any points yet)
select student_name, course_name,credit_points_obt,credit_points_reqd
FROM enrolment (SELECT student_full_name, SUM(credit_points) AS credit_points_obt
FROM enrolment
GROUP BY student_id),
Totally stuck...I have no idea where to go now.
You can sum conditionally to get points for subject. If none are given result will be null, so you filter out those student/course pairs in having clause.
I've changed > 50 condition to >= 50 because your results contradict your requirements. Also, by the data I'd say that you have omitted student table for brewity, but if you haven't, it is a must.
Live test is # Sql Fiddle.
select enrolment.student_name,
course.course_name,
course.credit_points_reqd,
sum(case when enrolment.results >= 50
then subject.credit_points
end) credit_points_obt
FROM enrolment
inner join course
on enrolment.course_code = course.course_code
inner join subject
on enrolment.subject_code = subject.subject_code
group by enrolment.student_name,
course.course_name,
course.credit_points_reqd
having sum(case when enrolment.results >= 50
then subject.credit_points
end) is not null

SQL: Find all previous records for a subset of IDs

I'm new to SQL and I am having trouble even starting this query.
If a student has a record in '2012', list that record and all of their previous records.
A simplified data set:
ASSIGNMENTS
STUDENT_ID BOOK_TITLE TERM
001 MOBY DICK 2009
002 ULYSSES 2009
003 HAMLET 2009
004 1984 2009
005 HAMLET 2009
004 WAR & PEACE 2010
003 THE TRIAL 2010
004 MOBY DICK 2011
001 -NULL---- 2012
004 -NULL---- 2012
Results should be the record of those registered in a given term followed by that student's previous records. The goal is for the user to look at currently registered students (NULL value in book title) and make sure they don't assign a book the student has already read.
STUDENT_ID BOOK_TITLE TERM
001 -NULL---- 2012
001 MOBY DICK 2009
004 -NULL---- 2012
004 MOBY DICK 2011
004 WAR & PEACE 2010
004 1984 2009
Any pointers/starting directions would be greatly appreciated! I have tried messing around with 'with', multiple inner joins, but I am not getting anywhere. I keep thinking about if..then syntax that doesn't really work in SQL?
SELECT STUDENT_ID, BOOK_TITLE, TERM
FROM ASSIGNMENTS
WHERE STUDENT_ID IN
(SELECT DISTINCT STUDENT_ID FROM ASSIGNMENTS WHERE TERM = 2012)
ORDER BY STUDENT_ID, TERM DESC
To come up with this answer first I created a query that matched your expected result format. Then I added the where criteria for "only students currently registered".
If you want to parameterize it put #Term instead of 2012. You could also run it off null book titles using WHERE BOOK_TITLE IS NULL
I don't know whether those -NULL---- values represent actual values or NULL values. Assuming the latter, here is one way to do it:
SELECT student_id, book_title, term
FROM assignments
WHERE student_id IN ( SELECT student_id FROM assignments WHERE book_title IS NULL )
A better way might be to retrieve data based on whether the student is registered for the current year's term. How to do that will depend on your RDBMS and version.