Filtering Dates in mySQL - mysql

Just started learning SQL and need help on the Feb 1, 2020 part.
The database has three tables for tracking horse-riding lessons:
Horse with columns:
ID - primary key
RegisteredName
Breed
Height
BirthDate
Student with columns:
ID - primary key
FirstName
LastName
Street
City
State
Zip
Phone
EmailAddress
Lesson Schedule with columns:
HorseID - partial primary key, foreign key references Horse(ID)
StudentID - foreign key references Student(ID)
LessonDateTime - partial primary key
Write a SELECT statement to create a lesson schedule for Feb 1, 2020 with the lesson date/time, student's first and last names, and the horse's registered name. Order the results in ascending order by lesson date/time, then by the horse's registered name. Make sure unassigned lesson times (student ID is NULL) appear in the results.
Hint: Perform a join on the LessonSchedule, Student, and Horse tables, matching the student IDs and horse IDs.
This is what I have; not sure of the correct way to go about it. I've tried using WHERE and AND but get an error or only all NULL first/last names in the table.
SELECT LessonDateTime, FirstName, LastName, RegisteredName
FROM LessonSchedule
LEFT JOIN Student ON LessonSchedule.StudentID = Student.ID
INNER JOIN Horse ON LessonSchedule.HorseID = Horse.ID
ORDER BY LessonDateTime, RegisteredName;

Please try this.
I think it will work.
SELECT LessonDateTime, FirstName, LastName, RegisteredName
FROM LessonSchedule
LEFT JOIN Student ON LessonSchedule.StudentID = Student.ID
INNER JOIN Horse ON LessonSchedule.HorseID = Horse.ID
WHERE LessonDateTime = '2020-02-01'
ORDER BY LessonDateTime, RegisteredName;

Related

SQL query employee and task table

I have an employee and a task table like this:
Table employees
id not null primary key,
name
Table Tasks
id primary key,
author id not null references employees (id),
assigneeid references employees (id)
I am trying to write a query that would return task id, author name, and assignee name and if there is no assignee name then I want to return null. FYI, this is not a homework question but I'm learning backend development and I need to brush up my sql skills.
UPDATE:
Here is the expected output
-- Expected output (in any order):
-- id author assignee
-- ----------------------
-- 1 Richard
-- 2 Lily Richard
You are looking for two left joins:
select t.*, eau.name as author, eas.name as assignee
from tasks t left join
employees eau
on eau.id = t.author_id left join
employees eas
on eas.id = t.assignee_id;

how does the count function in mysql work?

First and foremost, this is part of an assignment, but I'm trying to get more clarification on how the count() function works when querying a db.
The question is: List the name, SSN and the number of courses the student has taken (courses with the same CourseNumber taken in different quarters are counted as different courses).
I've been querying using this:
SELECT S.Name, S.SSN, COUNT(*)
FROM Student S, Enrollment E
WHERE S.SSN = E.SSN
GROUP BY S.SSN
which seems to return the correct answer, but I'm not sure why. As a result, I can't seem to get the next questions (assuming courses with the same CourseNumber taken in different quarters are considered as one course) correct.
Here are the create table commands so you can see which table holds what info:
CREATE TABLE Student(
SSN INT(9),
Name VARCHAR(20),
Major VARCHAR(30),
PRIMARY KEY (SSN)
);
CREATE TABLE Course(
CourseNumber INT(5),
PrerequisiteCourseNumber INT(10),
CourseTitle VARCHAR(10),
NumberUnits INT(2),
PRIMARY KEY (CourseNumber)
);
CREATE TABLE Section(
CourseNumber INT(5),
Quarter VARCHAR(10),
RoomNumber INT(5),
DayTime VARCHAR(20),
PRIMARY KEY (CourseNumber,Quarter),
FOREIGN KEY (CourseNumber) REFERENCES Course(CourseNumber)
);
CREATE TABLE Enrollment(
SSN INT(9),
CourseNumber INT(5),
Quarter VARCHAR(10),
Grade VARCHAR(1),
PRIMARY KEY (SSN,CourseNumber,Quarter),
FOREIGN KEY (SSN) REFERENCES Student(SSN),
FOREIGN KEY (CourseNumber) REFERENCES Course(CourseNumber),
FOREIGN KEY (Quarter) REFERENCES Section(Quarter)
);
Any pointers?
what you are doing is using old join syntax (pre ansi syntax) where you do a cross join of tables and use the where to turn it into a join. an equivalent query would be this.
SELECT S.Name, S.SSN, COUNT(*)
FROM Student S
JOIN Enrollment E ON S.SSN = E.SSN
GROUP BY S.SSN
Now to answer your question about what the count is doing and stuff..
COUNT() returns a count of every row that is returned.
GROUP BY groups all of the records by a common ground aka your SSN field. so if a student has 5 SSN rows in the table then his count will be 5.
Now for the part you are looking for with course numbers.. you need to JOIN those tables on appropriate fields and add a field to your group by for each quarter
aka add to the previous code..
WHERE E.quarter = whatever_quarter_you_want
you can add more to this query if you need to. but add data to your question if you want a more full answer.
Your current query is:-
SELECT S.Name, S.SSN, COUNT(*)
FROM Student S
INNER JOIN Enrollment E
ON S.SSN = E.SSN
GROUP BY S.SSN
What this is doing is joining student to enrollment, so giving multiple rows for each student, one for each course / quarter they are enrolled on. It is then grouped by SSN (student number?) to count up the number of course / quarters they are enrolled on. You should really group by S.Name as well (while MySQL won't object, most flavours of SQL would).
Note that COUNT(*) counts the number of rows. You could use COUNT(E.CourseNumber) which would count the number of rows where course number is not null. Not really useful here, but can be useful with LEFT OUTER JOINs. You can also use COUNT(DISTINCT CourseNumber) to count the number of unique non null course numbers for the student.
A LEFT OUTER JOIN might also be better as this would enable you to return 0 as the counts for students who exist but who are not enrolled in any courses:-
SELECT S.Name, S.SSN, COUNT(DISTINCT E.CourseNumber)
FROM Student S
LEFT OUTER JOIN Enrollment E
ON S.SSN = E.SSN
GROUP BY S.Name, S.SSN
SELECT S.Name, S.SSN, COUNT(*)
FROM Student S, Enrollment E, Section Sec, Course C
WHERE S.SSN = E.SSN AND E.CourseNumber = Sec.CourseNumber
AND Sec.CourseNumber = C.CourseNumber AND Sec.Quarter like E.Quarter
GROUP BY S.Name, S.SSN

Querying SQL with four tables

Can someone explain me how to query these tables to get number of employees in companies for each country they are present in? Number of resulting columns should be 3, Company, Country and Employees. Company and Branch are connected but Country is connected with City so I am not sure how to solve this. Thanks guys, appreciate it!!!
CREATE TABLE country (
id integer NOT NULL PRIMARY KEY,
name varchar NOT NULL,
population integer check(population > 0)
);
CREATE TABLE city (
id integer NOT NULL PRIMARY KEY,
name varchar NOT NULL,
population integer check(population > 0),
country integer NOT NULL REFERENCES country(id)
);
CREATE TABLE company (
id integer NOT NULL PRIMARY KEY,
name varchar NOT NULL
);
CREATE TABLE branch (
company integer NOT NULL REFERENCES company(id),
city integer NOT NULL REFERENCES city(id),
name varchar,
employees integer NOT NULL,
PRIMARY KEY (company, city)
);
This is what I did but I know it is wrong, I tried my combinations but so far nothing was correct!
SELECT
branch.employees,
company.name AS company,
country.name AS country
FROM branch
INNER JOIN company
ON branch.company = company.id
INNER JOIN country
ON city.country = country.id
ORDER BY country;
SELECT
company.name AS company,
country.name AS country,
sum(branch.employees) AS country_employees
FROM branch
JOIN company ON company.id = branch.company
JOIN city ON city.id = branch.city
JOIN country ON country.id = city.country
GROUP BY company.name, country.name
ORDER BY country.name, company.name;
You want to sum over the number of employees per company, for each of the countries they work in. This means that you have to GROUP BY those two fields while you SUM the number employees per branch. You need to use the city table as well, even though you do not display any data from it.
Read up on aggregate functions for more background information.

Joining Tables w/out foreign key

Is it possible to connect tables without foreign key?
For example
tblstudent
Columns:
id
firstname
lastname
middlename
tblgrade
Comluns:
id
quiz
project
exam
tblfinalgrade
Columns:
firstname
lastname
finalgrade
Is it possible to view final grade when searching for and id?
The id in tblStudent is meaningless because you are not referencing it in your other tables. Change your table structure to include this StudentId rather than First Name and Last Name.
For example:
tblGrade
columns:
GradeId
StudentId
Quiz
Project
Exam
tblFinalGrade
FinalGradeId
StudentId
FinalGrade
You can then do:
SELECT ID, FirstName, LAstName, Quiz, Project, Exam, FinalGrade
FROM tblStudent
INNER JOIN tblGrade ON tblGrade.StudentId = tblStudent.StudentId
INNER JOIN tblFinalGrade ON tblFinalGrade.StudentId = tblStudent.StudentId
This would be a better structure than joining on FirstName and Last Name just incase you ever have 5 John Smith how do you know you are returning the correct grades?
Although I am slightly against your original design, you can perform the same query with your existing structure by running the following query:
SELECT ID, FirstName, LAstName, Quiz, Project, Exam, FinalGrade
FROM tblStudent
INNER JOIN tblFinalGrade ON tblFinalGrade.FirstName = tblStudent.FirstName AND tblFinalGrade.LastName = tblStudent.LastName
WHERE tblStudent.ID = 1

ForeignKey Referencing Same Table

There was an interview test in which below was the table and structure
Table Person = id, name, dob, dod, mother_id, father_id
Primary Key (id)
Foreign Key mother_id references Person
Foreign Key father_id references Person
and it was asked
"select all who are mothers"
"select those child who are children of 'John Smith' and 'Jane'
and I was puzzled because I was assuming that foreign key would be linked with some other table as usual. But at that point I failed. do some one know the actual answer and reason?
This kind of data structure is called a "Self Referencing Table"
SELECT DISTINCT mothers.*
FROM person
inner join person mothers on person.mother_id = mothers.id
and
SELECT person.*
FROM person
inner join person fathers on person.father_id = fathers.id
inner join person mothers on person.mother_id = mothers.id
WHERE
fathers.name='john smith'
and
mothers.name='jane'
You can always have foreign key that link to the same table.. There is not problem in that..
See, suppose you are storing a person record in the table, now that person would be having mother and father. And mother and father both are themselves a person.. so, they are itself a record of the same table..
Suppose you have following two records in Person table: -
id name age mother_id
1 xyz 24 5
5 abc 57 6
So, from the above table you see that, person with id = 5 is actually mother of person with id = 1.. So, it is a foreign key referencing the same table..
So, here rather than performing a join operation with a different table, you have to perform join with the same table..
SELECT p2.id FROM
Person p1 join Person p2
WHERE p1.mother_id = p2.id
This query will select the record of mother of your current record..
I was assuming that foreign key would be linked with some other table
as usual.
It still is - it references other records in the same Person table.
-- All Mothers
SELECT mom.name
FROM Person mom
WHERE EXISTS (SELECT 1 FROM Person WHERE mother_id = mom.id);
-- Children of John Smith and Jane
SELECT kid.name
FROM Person kid
INNER JOIN Person mom on kid.mother_id = mom.id
INNER JOIN Person dad on kid.father_id = dad.id
WHERE mom.name = 'Jane' AND
dad.name = 'John Smith';
Have a look at this SQL fiddle here
SELECT *
FROM Person
WHERE father_id = (SELECT id FROM Person WHERE name = 'John Smith')
AND mother_id = (SELECT id FROM Person WHERE name = 'Jane')
The answer was already given by podiluska, just explaining how it works since it looks like you're new to MySql.
By giving an Alias to a table(like mother or father to the table person) you do something like a pseudo-table, that the MySql interprets as another table, so the join happens normally, just imagine there are 3 tables now. Person, Father and Mother, and they are all linked together by the join.