Nested Query Issue - mysql

I have two tables, a NextOfKin table and a Course table, the NextOfKin table has the following attributes:
StudentID
ContactTelNo
And the course has this one (only showing relevant attributes):
CourseNo
I am trying to get an output where I show the studentID and contactTelNo for the next of kin of all students on course with courseNo equal to 1001.
This is the code I'm attempting to run
SELECT studentID, contactTelNo
FROM NextOfKin
WHERE courseNo =
(SELECT courseNo
FROM Course
WHERE courseNo = '1001')
I'm currently getting an error message that says "Unkown coloumn 'courseNo' in 'where clause'
where am I going wrong?
p.s I can only used a nested query and not a join

The subquery needs to return student IDs, not course numbers, since that's what's in the NextOfKin table. And you need to use IN rather than = to check for membership in a set:
SELECT studentID, contactTelNo
FROM NextOfKin
WHERE studentID IN
(SELECT studentID
FROM Course
WHERE courseNo = '1001')

Assuming Course also has a StudentID column, you want this:
SELECT NextOfKin.studentID, NextOfKin.contactTelNo
FROM NextOfKin
INNER JOIN Course ON Course.StudentID = NextOfKin.StudentID
WHERE Course.courseNo ='1001'
If Course does NOT have a StudentID column, you're looking at the wrong table. Somewhere you will have a table with columns for both StudentID and CourseNo values. It might be called something like Enrollments or Registrations.

Related

Does using nested queries adds semantics to the sql query over simple query

create table students(id int,
name varchar(20),
dept varchar(10),
salary int default 10000
);
Insert into students values(1,'Ram','HR',10000);
Insert into students values(2,'Amrit','Mrkt',20000);
Insert into students values(3,'Ravi','HR',30000);
Insert into students values(4,'Raju','finance',40000);
Query which my tutor told me:
select name from employee where dept in(select dept from emp group by dept having count(*)<2);
he told that we should only use that attribute with select statement which has been used in group by and other attributes cannot be used.
But the following query also works:
select name from employee group by dept having count(*)<2;
is my query correct or wrong? if it is correct what is the advantage of using it as nested query than simple query?
If you have only one matching row, then you can use:
select max(name)
from employee
group by dept
having count(*) = 1;
The having clause guarantees one match. The max() returns the value in the one row.
This is fine, but not very orthodox -- it doesn't generalize very well. The form that your tutor suggests is more generalizable. It will readily adapt to looking for employees in departments with 2 employees or 7 or whatever.

MySQL Change column value to the least value in its category

Assuming only one school can be identified in a specific town, you are required to move students from duplicated schools to originally created schools. We also assume that lowest school id implies the first schools to be created in
the database, hence original schools.
I want to achieve this simply by changing the school ids for duplicate school+town to the smallest school id (the original) in that category. This will take care of the student records table that is linked to this one via foreign key (school id).
How would I go about doing this on the table attached? I'm thinking along the lines of SELECT MIN, CASE STATEMENTS as well as GROUP BY and COUNT() but I'm at a loss on how to combine these. Anyone have an idea/code on how I would achieve the requirement above?
I'd assume that the school id is a unique identifier (key). Therefore you can't just update it in the schools table. You'd rather need to update the school_id column in the students table to point to the original school's id.
If this is the case you can do something along the lines of
-- get all students and their current school info for update
UPDATE students st JOIN schools sc
ON st.school_id = sc.id JOIN (
-- get ids of original schools
SELECT town, name, MIN(id) id
FROM schools
GROUP BY town, name
) q -- join students with a list original schools ids
ON sc.town = q.town AND sc.name = q.name
-- change the school id to the original one
SET st.school_id = q.id
-- but only for students that were associated with non-original schools
WHERE st.school_id <> q.id
Here is dbfiddle demo

writing a SQL statement to display course numbers by an individual

I'm trying to display course number of class by an individual teacher. The course and teacher's id info is on one table and the teacher's id info and name info is on another table. I can get the correct answer for each statement when entered individually but not when combined. so if I have:
select course_no, instructor_id from class;
this gives me the course number and instructor's id
then if i do
select first_name
, last_name
, instructor_id
from instructor
where First_name = 'specific first_name'
and 'specific last_name'
this gives me the instructors id, first & last name but when i join these two i get an error. what I'm i missing

Problems Creating table

I want to create a table and populate it with records. the new table should be named majorlist and should include the student ID, the student name ( first and last names concatenated with a space in between), major and the age (In whole years) of each student. label the output columns SID, Name, Major, and Age.
create table majorlist
select studentid as 'SID' from students
select concat(firstname,' ',lastname) as "name" from students
select major as 'major' from students
select round((datediff(now(),DOB))/365) as "age" from students;
I know each one of these works separately but I cant figure out how to integrate them into a table without getting a error. I try removing the select statments from each one and still that doesnt work.
create table majorlist
select studentid as 'SID',
concat(firstname,' ',lastname) as "name",
round((datediff(now(),DOB))/365) as "age"
from students;
Yes the answer by #juergen d is good. You are creating the table by fetching a single table values students.
Then its better to use a single select statement for fetching. You can use the query like -
create table majorlist
select studentid as 'SID',
concat(firstname,' ',lastname) as 'name',round((datediff(now(),DOB))/365) as 'age'
from students;

Cross table query

I have three tables.
course
idcourse
name
mark
idmark
idstudent
idcourse
mark
student
idstudent
name
How to cross a query to such a result?
result
table Header
studentid course1 course2 ... courseN
id1 mark1 mark2 ... markN
id2 mark1 mark2 ... markN
id3 mark1 mark2 ... markN
Best I can think if is to use the group_concat function.
Because a variable number of columns is just a maintenance nightmare.
You can strip the values from the coursegrades field apart by exploding the list in php or whatever comma separator you have in your client.
/*First make a list of coursenames for the header.*/
SELECT 'studentid' as idstudent
, 'studentname' as studentname
, GROUP_CONCAT(course.name ORDER BY couselist.idcourse) as coursegrades
FROM course
INNER JOIN (SELECT DISTINCT idcourse FROM mark) courselist
ON (courselist.idcourse = course.idcourse)
UNION ALL
/*UNION ALL this with a list of grades per course*/
SELECT idstudent
, student.name as studentname
, GROUP_CONCAT(IFNULL(mark.mark,'') ORDER BY courselist.idcourse) as coursegrades
FROM course
INNER JOIN (SELECT DISTINCT idcourse FROM mark) courselist
ON (courselist.idcourse = course.idcourse)
LEFT JOIN mark ON (mark.idcourse = courselist.idcourse)
INNER JOIN student ON (student.idstudent = mark.idstudent)
GROUP BY student
First you should have many-to-one foreign key relationships to insure that the idstudent field in the tables depending on the student table idstudent field (mark, course) match up.
To answer your specific question, it's not possible to return a result like this from the database client. Maybe if you wrote something as a procedure, but not with basic SQL. The best way to get the results you want is to do a simple query on the mark table to get the idstudent and mark fields and then manipulate them externally in another language.
So the query would be like this:
SELECT marks.idstudent, marks.mark, courses.name FROM marks,courses
WHERE marks.idcourse=courses.idcourse;
And you can display the results using an external program written in PHP or Python, for example.