Let's assume that we want to capture some of the basic information that is stored within the MIDS system at the Academy (Information that is usually provided by the Midshipmen - Query Academic Information page). An Example.
What type of table schema would you create for these tables? The examples, Midshipmen and Grades are very rudimentary tables that only partially cover the information of the page, but will be used for the examples in this lesson. The page insert_Midn_data.sql can be used to populate this information into your databases.
If you review the schemas for those two tables, you will see that they share the Alpha column and nothing else. One table contains the information about the midshipmen, while the other will hold their Grades. If we want to run queries that return information from both tables at the same time we will need to join these two tables in our queries. Below are selected columns from both tables.
| Alpha | Last | First | Birthdate | SATM | SATV | HighSchoolState |
|---|---|---|---|---|---|---|
| 261000 | Stark | Eddard | 1956-08-14 | 710 | 640 | AK |
| 261001 | Stark | Rob | 1994-03-24 | 510 | 740 | AK |
| 261002 | Stark | Bran | 1999-12-11 | 800 | 770 | AK |
| 261234 | Lannister | Tyrian | 1995-01-01 | 780 | 790 | GA |
| 261235 | Lannister | Cersei | 1993-02-14 | 580 | 620 | GA |
| 261236 | Lannister | Tywin | 1945-09-12 | 630 | 410 | GA |
| 261237 | Lannister | Jaime | 1993-02-15 | 350 | 510 | GA |
| Alpha | AcYr | Sem | Course | Title | 6Week | 12Week | Exam | CourseGrade |
|---|---|---|---|---|---|---|---|---|
| 261001 | 2023 | SPRING | NL110 | Preparing to Lead | A | B | F | F |
| 261002 | 2023 | SPRING | NL110 | Preparing to Lead | B | C | B | A |
| 261234 | 2023 | SPRING | HE111 | Rhetoric and Intro to Literature | B | B | B | |
| 261234 | 2023 | SPRING | HH104 | American Naval History | A | A | A | A |
| 261234 | 2023 | SPRING | NL110 | Preparing to Lead | A | A | B | A |
| 261234 | 2023 | SPRING | NS101 | Fundamentals of Seamanship | B | B | B | B |
| 261234 | 2023 | SPRING | SC111 | Foundations of Chemistry I | C | C | D | C |
The SELECT statement is used to retrieve information from a database. Basic syntax:
SELECT [DISTINCT] column_name(s)|*
FROM table_name(s)
[WHERE conditions]
[ORDER BY column(s) [ASC | DESC]]
We will now expand our work with the FROM and WHERE clauses so that we can join information from more than one table. There are two important steps: all of the tables that will be used must be added to the FROM statement, and we must link them in the WHERE statement. As an example, what if we wanted to find the names of the students who are in NL110 using the data above?
SELECT m.Alpha, First, Last
FROM Grades g, Midn m
WHERE g.Alpha = m.Alpha AND Course = 'NL110';
| Alpha | First | Last |
|---|---|---|
| 261001 | Rob | Stark |
| 261002 | Bran | Stark |
| Tyrian | Lannister |
A table referenced in the FROM clause of a SELECT query can be aliased using
table_name alias_name
or we can add AS to make our actions more obvious and our code more readabletable_name AS alias_name
and the alias_name (usually shorter than the table_name) can be used for that
query.
The SQL SELECT query will be evaluated using the following conceptual strategy (in reality a more efficient strategy is used):
| Alpha | AcYr | Sem | Course |
|---|---|---|---|
| 261001 | 2023 | SPRING | NL110 |
| 261002 | 2023 | SPRING | NL110 |
| Alpha | Last | First |
|---|---|---|
| 261000 | Stark | Eddard |
| 261001 | Stark | Rob |
| 261002 | Stark | Bran |
| Alpha | AcYr | Sem | Course | Alpha | Last | First |
|---|---|---|---|---|---|---|
| 261001 | 2023 | SPRING | NL110 | 261000 | Stark | Eddard |
| 261001 | 2023 | SPRING | NL110 | 261001 | Stark | Rob |
| 261001 | 2023 | SPRING | NL110 | 261002 | Stark | Bran |
| 261002 | 2023 | SPRING | NL110 | 261000 | Stark | Eddard |
| 261002 | 2023 | SPRING | NL110 | 261001 | Stark | Rob |
| 261002 | 2023 | SPRING | NL110 | 261002 | Stark | Bran |
| Alpha | AcYr | Sem | Course | Alpha | Last | First |
|---|---|---|---|---|---|---|
| 261001 | 2023 | SPRING | NL110 | 261001 | Stark | Rob |
| 261002 | 2023 | SPRING | NL110 | 261002 | Stark | Bran |
| Alpha | Last | First |
|---|---|---|
| 261001 | Stark | Rob |
| 261002 | Stark | Bran |
What happens when we try to return the Alpha and do not specify from which table it comes?
SELECT First, Last, Alpha
FROM Midn m, Grades g
WHERE m.Alpha = g.Alpha AND g.Course = 'NL110';
ERROR 1052 (23000): Column 'Alpha' in field list is ambiguous
Since both tables have the column Alpha, the database system does not know which one to provide,
and it is not going to make the assumption that they are the same! You will have to choose!
SELECT First, Last, m.Alpha
FROM Midn m, Grades g
WHERE m.Alpha = g.Alpha AND g.Course = 'NL110';
MySQL has support built in for basic arithmetic and there are five aggregating functions we will focus on: COUNT, SUM, AVG, MIN, and MAX.
SELECT First, Last, SATM+SATV AS SAT FROM Midn;
| First | Last | SAT |
|---|---|---|
| Eddard | Stark | 1350 |
| Rob | Stark | 1250 |
| Bran | Stark | 1570 |
| Tyrian | Lannister | 1570 |
| Cersei | Lannister | 1200 |
| Tywin | Lannister | 1040 |
| Jaime | Lannister | 860 |
You may have noticed that it added the two values together, and we renamed the resulting column using the AS keyword!
Now trying some of the aggregate operators we can work on the entire data set at once. Review the following examples:
SELECT AVG(SATM+SATV) AS AverageSAT
FROM Midn;
| AverageSAT |
|---|
| 1262.8571 |
SELECT COUNT(*) AS TotalStudents
FROM Midn;
| TotalStudents |
|---|
| 7 |
SELECT SATM+SATV AS SAT, First, Last
FROM Midn
WHERE SATM+SATV = (SELECT MIN(SATM+SATV) FROM Midn);
| SAT | First | Last |
|---|---|---|
| 860 | Jaime | Lannister |
If we wanted to find the the lowest grade in each class, we could attempt run a separate query for each course in the database.
SELECT MAX(CourseGrade)
FROM Grades
WHERE Course = 'NL110';
| MAX(CourseGrade) |
|---|
| F |
SELECT Course, MAX(CourseGrade)
FROM Grades
GROUP BY Course;
| Course | MAX(CourseGrade) |
|---|---|
| HE111 | B |
| HH104 | A |
| NL110 | F |
| NS101 | B |
| SC111 | C |
The SQL query will be evaluated using the following strategy:
The HAVING clause allows us to further restrict the results of the GROUP BY by removing groups that do not meet the additional constraints.
SELECT Course, MAX(CourseGrade)
FROM Grades
GROUP BY Course
HAVING MAX(CourseGrade) > 'B';
| Course | MAX(CourseGrade) |
|---|---|
| NL110 | F |
| SC111 | C |