I am using mySQL to query a mock university database. This is for a class so. The query I am trying to make is to this question:
Find the names and ids of the students who have taken exactly one
course in the Spring 2010 semester.
schema tables:
student(id, name, dept_name, total_cred)
takes(id, course_id, sec_id, semester, year, grade)
I can query the schema for all students who took classes in Spring of 2010 no problem. But where I run into trouble is the 'exactly one class' part.
select distinct s.id, name
from student s join takes
where semester = 'Spring' and
year = 2010;
I thought I would use a set operator like not in to compare that result to another that returns the number of classes taken by each student:
select distinct count(s.id) num_classes, name
from student s join takes
where semester = 'Spring' and
year = 2010
group by name
The problem is that when I run this query it returns the count of 8 for each name. But I have no idea where it is getting that number because there is nothing that occurs exactly 8 times.
My question(s):
1) am I going about this the right way?
2) If so what am I doing wrong to make the count return that way?
Try this:
select s.id, s.name
from student s join takes t on s.id = t.id
where t.semester = 'Spring' and
t.year = 2010
group by s.id, s.name
having count(*) = 1
Related
I'm having some doubts regarding these answers of mine, would greatly appreciate if you guys can clarify if im right or wrong,
Questions:
An employee may be assigned to more than one project and a project may have many employees. Consider the following relational schema and write SQL statements for the below queries.
Employees (empID, empName, empDOB, empAddress, salary, deptID, jobID)
Assignments (empID, projID, assignedDate, completionDate, status)
Projects (projID, projDescription, startDate, endDate, projType)
(a) Display the names of employees who were born before 31st Jan 1980 and assigned a ‘Office Complex’ type project, sort results in ascending order of name. (5 marks)
(b) Retrieve the empIDs who are assigned at least two (2) projects. (5 marks)
Answers:
(a) SELECT empName FROM Employees WHERE empDOB < '31-01-1980' AND projType = (SELECT projType FROM Projects WHERE projType = 'Office Complex') ORDER BY empName;
(b) SELECT empID FROM Employees GROUP BY (SELECT projID From Projects) HAVING COUNT(*)>1 ORDER BY empID;
I feel the answer for the second question may be wrong.
For part a), I'd join the tables to match up employees with the project type:
SELECT empName
FROM Employees
INNER JOIN Assignments ON Assignments.empID = Employees.empID
INNER JOIN Projects ON Assignments.projID = Projects.projID
WHERE empDOB < 31-01-1980 AND projType = 'Office Complex'
ORDER BY empName;
As it stands, your statement attempts to find projType = 'Office Complex' in the Employee table, where it doesn't exist.
For the second question, everything you need is in the Assignments table:
SELECT empID, COUNT(projID)
FROM Assignments
GROUP BY empID
HAVING COUNT(projID) > 1
I'm finding it a bit confusing to solve the following questions...
"
An employee may be assigned to more than one project and a project may have many employees. Consider the following relational schema and write SQL statements for the below queries.
Employees (empID, empName, empDOB, empAddress, salary, deptID, jobID)
Assignments (empID, projID, assignedDate, completionDate, status)`
Projects (projID, projDescription, startDate, endDate, projType)
(a) Display the names of employees who were born before 31st Jan 1980 and assigned a ‘Office Complex’ type project, sort results in ascending order of name.
(b) Retrieve the empIDs who are assigned at least two (2) projects.
"
My answer so far .
(a) SELECT empName FROM EMPLOYEES WHERE empDOB < '31-january-1980' AND ....
"
Please help me out
try this :
A)
SELECT employee.empName
FROM Assignments ass
JOIN Employees employee
ON employee .empID= ass.empID
JOIN Projects project
ON project.projID= ass .projID
WHERE employee.empDOB < '31-january-1980'
AND project.projType = ‘Office Complex’
ORDER BY employee.empName;
Without using JOIN CLAUSE
SELECT DISTINCT employee.empName
FROM Employees employee
WHERE employee.empDOB < '31-january-1980'
AND employee.empID IN (
SELECT ass.empID
FROM Assignments ass
WHERE ass.projID IN (
SELECT project.projID
FROM Projects project
WHERE project.projType = ‘Office Complex’
)
)
ORDER BY employee.empName ASC;
b)
SELECT ass.empID, COUNT(*) as counting
FROM Assignments ass
GROUP BY ass.empID
HAVING COUNT(*) >= 2;
I have a database and I want to create a view that allows the person to invoke the view name to see the "year, semester, credits", for the view. What I want to do is have it give me the year, then the semester and then the total credits taken per semester.
So, it should return a result if I have 2 students in spring 2010, and they took 2 classes each at 3 credit hours per class at a total of 12 credits, and so on and so fourth.
EX. '2010 Spring 12'
CREATE VIEW tot_cred26
AS
SELECT DISTINCT year, semester, COUNT(credits)
FROM course INNER JOIN takes;
Thanks again guys, super new to SQL and you all have been really helpful! :)
Use GROUP BY to combine rows for each set of values. And since you want the total credits, you should use SUM; COUNT just counts the number of rows. And your INNER JOIN needs an ON clause to specify how the two tables are related; I'm assume there's a courseid column in both tables.
CREATE VIEW tot_cred26 AS
SELECT year, semester, SUM(credits) as total_credits
FROM course AS c
INNER JOIN takes as t ON t.courseid = c.courseid
GROUP BY year, semester
Below Code may solve the problem:
CREATE VIEW tot_cred26
AS
SELECT year, semester, COUNT(credits) total_credits
FROM course INNER JOIN takes
group by year, semester
;
I couldn't end up retrieving data from multiple tables in a single query.
I have the following tables:
A brief explanation :
A student can study many subjects and subjects can be studied by many students (table Study Created)
A subejct is taught by a lecturer (FK used in (table Subject))
The table Grade gives infos about the marks obtained by a student
The SQL query I was trying to perfom is: Retrieve average students who study subjects taught by lecturer Antonio.
So first I used an AVG aggregation on table grade to get average students:
SELECT Id_Student, Name, AVG(Mark)
AS Average FROM Grade
GROUP BY Id_Student, Name
But my trouble is also to use the result of this SQL query and filter with again with the result of Subjects taught by Lecturer "Antonio".
Is it possible to make it in a one SQL query?
SELECT Id_Student, Name, AVG(Mark) AS Average FROM Grade
where id_student in
(
select student.id_student from subject
join study on subject.id_subject = study.id_subject
join student on study.id_student = student.id_student
where subject.taught_by = L1
)
GROUP BY Id_Student, Name
also you could probably just join GRADE instead of doing the subselect that I did here. But it's hard to tell how it will go without actually testing it.
I have a table that tracks attendance in a course. The columns are the courseid, lesson, personid, and date. I have a query (below) that extracts the earliest date a person appears along with the associated course, lesson, and personid. This is used to determine when a person started a particular course and ensure they started with the first lesson. This works fine, but where I am stuck is running this query per course. For example, finding the first date each person in a particular course started it rather than for every course. Right now I am just running the more general query and filtering it in the biz layer.
I obfuscated this a bit so forgive any typos:
select a.courseid,
a.lesson,
a.personid,
a.thedate
from (select personid,
min(thedate) as earliestdate
from attendance
group by personid) as x
inner join attendance as a on (a.personid = x.personid and a.thedate = x.thedate)
Just group over person_id, course in the inner query:
select a.courseid, a.lesson, a.personid, a.thedate
from (
select personid, courseid, min(thedate) as earliestdate
from attendance
group by personid, courseid
) as x
inner join attendance as a
on (a.personid = x.personid and
a.thedate = x.thedate and
a.courseid=x.course_id)
I have a small doubt here. Currently all the information is maintained in single data object/table. How would it be if we have different data model like below...?
Objext1:
Course table: Course details having lession with a relation
Student table: Contains student details.
Will the querying would be simplified in this way....?
Sorry if anything sounds immatur...
Regards,
UDAY