In the above relational schema, how would I do the following?:
List the names of all students that have a higher GPA than the minimum required GPA for the major they have applied for.
A couple of joins should do the trick:
SELECT s.*
FROM Student s
JOIN Apply a ON s.sId = a.sId
JOIN MinimumGPA m on m.major = a.major
WHERE s.gpa > m.mingpa
You use JOIN and NATURAL JOIN(this one is not required but i like it),
with join you ufse 2 tables giving 2 columns that need to be equal(you specify them in the WHERE), NATURAL JOIN does the same but assuming you have 1 or more columns with the same name(those are the ones natural join uses like if they were delared in the where)
So first you fuse MinimumGPA and Apply(they have 2 cols with the same name so natural join)
Select * FROM MinimumGPA NATURAL JOIN Apply
then, since you awhere asked for the NAMES of the students, you fuse that new table(giving it a name, in this case i used MinimumGPAApply, you could name it "the dogtable" if you wanted) with students, since the name on the columns isnt the same you use JOIN and specify the columns in the where, also you add the gpa condition
Select sName from Student JOIN (The first query) As MinimumGPAApply WHERE Student.sId = MinimumGPAApply.sID AND Student.GPA > MinimumGPAApply.minGPA
So at the end you end with somethign like this:
Select sName from Student JOIN (Select * FROM MinimumGPA NATURAL JOIN Apply) As MinimumGPAApply WHERE Student.sId = MinimumGPAApply.sID AND Student.GPA > MinimumGPAApply.minGPA
select s.Cname,s.gpa as studentGpa ,mg.mingpa as mingpaRequired from student s
inner join apply a on s.sid=a.sid
inner join major m on m.major=a.major
inner join minimumGPA mg on mg.major=m.major
where mg.mingpa<s.gpa
Related
I have a match table whose structure is displayed here
in this table i have column teama, teamb which are a foreign key columns referenced to team table's t_id. Basically, what i want to do is that when i select all data from this table i want it to display the values in teama, and teamb instead of their t_id. Structure of Team table is here
Query which i am writing is below:
select *
from teams,matches
where
matches.team_a=teams.t_id
and matches.team_b=teams.t_id;
You need to join 2 columns of matches to the teams table:
select
m.m_id,
t1.t_name as team_a,
t2.t_name as team_b,
m.m_time
from
matches m inner join teams as t1 on m.team_a=t1.t_id
inner join teams as t2 on m.team_b=t2.t_id
order by m.m_id;
First, never use commas in the FROM clause. Always use proper, explicit, standard JOIN syntax. You need two JOINs in fact:
select m.*, ta.t_name as name_a, tb.t_name as name_b
from matches m left join
teams ta
on m.team_a = ta.t_id left join
teams tb
on m.team_b = tb.t_id;
This uses left join just to ensure that you get all matches, even if one of the teams is missing. In this case, that is probably not an important consideration, so inner join would be equivalent.
You want two INNER JOINs from table matches to table teams, like :
SELECT
ta.t_name,
tb.t_name
FROM
matches m
INNER JOIN team as ta on ta.t_id = matches.team_a
INNER JOIN team as tb on tb.t_id = matches.team_b
You can create view after join it was make your work simple for further developement,i was improove mr.forbas code as follow
CREATE VIEW team AS select
m.m_id,
t1.t_name as team_a,
t2.t_name as team_b,
m.m_time
from
matches m inner join teams as t1 on m.team_a=t1.t_id
inner join teams as t2 on m.team_b=t2.t_id
order by m.m_id;
I am trying to convert the following 2 relational algebra into standard english but I am having trouble understand what exactly the INTERSECTS does
I know that INTERSECT finds the values that occur in both select statements
I have managed to find its SQL query, but I just can't figure out what it asks in plain english
Would anyone be able to help?
Relational Algebra:
Πstudent_name(σcourse id=“CS1850“(student Natural Join enrolled)) ∩
Πstudent_name(σcourse id=“CS1840“(student Natural Join enrolled))
SQL:
SELECT student_name FROM student NATURAL JOIN enrolled WHERE
course_id='CS1850' INTERSECT SELECT student_name FROM student
NATURAL JOIN enrolled where student_name='CS1840'
Second Expression:
Πstudent_name(σe1.student
id=e2.student_id∧e1.course_id<>e2.course_id(student natural join
(ρe1(enrolled) × ρe2(enrolled))))
SELECT student_name FROM student NATURAL JOIN enrolled e1 NATURAL JOIN
e2 WHERE e1.student_id = e2.student_id
First, don't use NATURAL JOIN. It is an error waiting to happen. It matches tables based on the names of columns in common. It doesn't even use properly declared foreign key relationships. Instead, use USING or ON to be explicit about the columns used for joining.
Second, you don't need INTERSECT. There are two typical methods that use GROUP BY or JOIN.
In English, the query gets the students that are enrolled in both classes.
SELECT s.student_name
FROM student s JOIN
enrolled e
USING (student_id) -- or whatever
WHERE e.course_id IN ('CS1850', 'CS1840')
GROUP BY s.student_name
HAVING COUNT(*) = 2;
Note: This assumes that two students do not have the same name.
An alternative just uses JOIN:
SELECT s.student_name
FROM student s JOIN
enrolled e1
USING (student_id) JOIN
enrolled e2
USING (student_id)
WHERE e1.course_id = 'CS1850' AND
e2.course_id = 'CS1840';
If the underlying tables do not have duplicates, then this doesn't need a GROUP BY or DISTINCT.
I have the two tables STUDENT and TaskEffort.
Many students have worked on same tasks. For a particular task the name of the students and effort should be considered.
The STUDENT table contains studentid, firstName and lastName.
The TaskEffort table contains taskid, studentid and Effort
I need to display the taskid, first name, last name, effort, for those who worked on a particular task.
This is one of the queries I tried, but this is not working.
SELECT t.id, s.firstname, s.lastname, t.effort
FROM taskeffort t
LEFT OUTER JOIN student s ON t.id = 4 AND s.studentid = t.studentid
Thanks in advance.
First the design is not accurate.
You said that "Many students must have worked on same task" but your design is
1-many students. It means that each task has only one student. You need to change the design to support you requirements.
this relation is many-to-many. Student can be assigned to many tasks and tasks may have been assigned to many students.
Add a third table called taskAssignments with columns: student_id,task_id and remove student_id column from TaskEffort.
Then run this query:
SELECT t.id, s.firstname, s.lastname, t.effort
FROM TaskEffort t
LEFT JOIN taskAssignments ta ON t.id=ta.task_id
LEFT JOIN student s ON s.studentid = ta.studentid
WHERE t.id = 4
SELECT t.id, s.firstname,s.lastname, t.effort
FROM taskeffort t
LEFT OUTER JOIN student s ON s.studentid = t.studentid
WHERE t.id = 4;
What happens actually when we use cascaded join statements
select student.name, count(teacher.id)
from student
left join course on student.course_id = course.id
left join teacher on student.teacher_id = teacher.id
group by student.name;
It seems when I used only the first left join alone it returned 30 rows while using the second left join alone returned 20 rows. But using together returns 600 rows. What is actually happening ? Does the result from the first left join is used in the second ? I don't understand the semantics. Help me understand it.
Since you don't have any join conditions between teacher and course, you're getting a full cross-product between each of the other two joins. Since one join returns 20 rows and the other returns 30 rows, the 3-way join returns 20x30 = 600 rows. Its equivalent to:
SELECT t1.name, count(t2.id)
FROM (SELECT student.name
FROM student
LEFT JOIN course ON student.id = course.id) AS t1
CROSS JOIN
(SELECT teacher.id
FROM student
LEFT JOIN teacher ON student.id = teacher.id) AS t2
GROUP BY t1.name
Notice that the CROSS JOIN of the two subqueries has no ON condition.
The correct way to structure this database is as follows:
student table: id (PK), name
course table: id (PK), name, fee, credits
student_course table: id (PK), student_id (FK), course_id (FK), unique key on (student_id, course_id)
Then to get the name of each student and the average course fee, you would do:
SELECT s.name, AVG(c.fee) AS avg_fee
FROM student AS s
LEFT JOIN student_course AS sc ON s.id = sc.student_id
LEFT JOIN course AS c ON sc.course_id = c.id
All Mysql joins are graphically explained here. Take a look and choose correct joins for both joined tables.
How would you reference table1 columns to 2 columns in table 2
I created a table 'State' with 50 exact rows
trying to relate (weddingState,contactState) in 'Wedding' table
This is the statement that I created but it only joins the top WeddingState correctly - seems not to care about the INNER Join below it...
SELECT *
FROM weddings
INNER JOIN states as s1 ON weddings.WeddingState = s1.StateId //state of marriage
INNER JOIN states as s2 ON weddings.ContactState = s2.StateId //contact state of bride
WHERE weddings.weddingid="094829292"
I'd guess that you're retrieving these in PHP or something, and you're fetching the rows in a hash-array, keyed by the field name. Of course there can only be one element in a hash with a given key. So you need to use column aliases to make sure columns with the same name are given a distinct alias.
SELECT w.*, s1.StateID AS wstate, s2.StateId AS cstate
FROM weddings AS w
INNER JOIN states AS s1 ON w.WeddingState = s1.StateId //state of marriage
INNER JOIN states AS s2 ON w.ContactState = s2.StateId //contact state of bride
WHERE w.weddingid="094829292";
Now your hash-array will have keys "wstate" and "cstate". Without aliasing these columns, one will always overwrite the other.
And what are you getting for your result that leads you to your conclusion?
It's going to be confusing for starters because the field names in the two joins, plus some of the field names in the primary table, are identical. It's a really good idea to explicitly choose your output columns and give them meaningful aliases.
How about:
SELECT s1.StateName, s2.StateName
FROM weddings
INNER JOIN states as s1 ON weddings.WeddingState = s1.StateId //state of marriage
INNER JOIN states as s2 ON weddings.ContactState = s2.StateId //contact state of bride
WHERE weddings.weddingid="094829292"
Thanks Bill, I added the StateName as well
SELECT w.*,
s1.StateId AS WeddingStateId,
s1.StateName AS WeddingStateName,
s2.StateId AS ContactStateId,
s2.StateName AS ContactStateName
FROM weddings AS w
INNER JOIN states AS s1 ON w.WeddingState = s1.StateId
INNER JOIN states AS s2 ON w.ContactState = s2.StateId