Sid | Name | Login | Age | Gpa |
---|---|---|---|---|
53666 | Kanye | kanye@cs | 44 | 4.0 |
53688 | Bieber | jbieber@cs | 27 | 3.9 |
53655 | Tupac | shakur@cs | 25 | 3.5 |
Sid | Cid | Grade |
---|---|---|
53666 | 15-445 | C |
53688 | 15-721 | A |
53688 | 15-826 | B |
53655 | 15-445 | B |
53666 | 15-721 | C |
Cid | Name |
---|---|
15-445 | Database Systems |
15-721 | Advanced Database Systems |
15-826 | Data Mining |
15-823 | Advanced Topics in Databases |
(P.S. The SQL below all use example data table)
Ex: Which students age > 25?
SELECT name, gpa
FROM student
WHERE age > 25
Ex: Which students got an A in 15-721?
xxxxxxxxxx
SELECT s.name
FROM enrolled AS e, student AS s
WHERE e.grade = 'A' AND e.cid = '15 - 721'
AND e.sid = s.sid
Name | Definition |
---|---|
AVG(col) | Return the average col value |
MIN(col) | Return the minimum col value |
MAX(col) | Return the maximum col value |
SUM(col) | Return the sum of values in col |
COUNT(col) | Return # of values for col |
Ex: Get # of students with a "@cs" login?
xxxxxxxxxx
SELECT COUNT(login) AS cnt
FROM student WHERE login LIKE '%@cs'
xxxxxxxxxx
SELECT COUNT(*) AS cnt
FROM student WHERE login LIKE '%@cs'
xxxxxxxxxx
SELECT COUNT(1) AS cnt
FROM student WHERE login LIKE '%@cs'
xxxxxxxxxx
SELECT AVG(gpa), COUNT(sid)
FROM student WHERE login LIKE '%@cs'
xxxxxxxxxx
SELECT COUNT(DISTINCT login)
FROM student WHERE login LIKE '%@cs'
Get the average GPA of students enrolled in each course?
xxxxxxxxxx
SELECT AVG(s.gpa), e.cid
FROM enrolled AS e, student AS s
WHERE e.sid = s.sid
Project tuples into subsets and calculate aggregates against each subset.
xxxxxxxxxx
SELECT AVG(s.gpa), e.cid
FROM enrolled AS e, student AS s
WHERE e.sid = s.sid
GROUP BY e.cid
Non-aggregated values in SELECT output clause must appear in GROUP BY clause. For example:
xxxxxxxxxx
SELECT AVG(s.gpa), e.cid, s.name
FROM enrolled AS e, student AS s
WHERE e.sid = s.sid
GROUP BY e.cid, s.name
Filters results based on aggregation computation. Like a WHERE clause for a GROUP BY.
xxxxxxxxxx
SELECT AVG(s.gpa) AS avg_gpa, e.cid
FROM enrolled AS e, student AS s
WHERE e.sid = s.sid
GROUP BY e.cid
HAVING avg_gpa > 3.9;
String Case | String Quotes | |
---|---|---|
SQL-92 | Sensitive | Single Only |
Postgres | Insensitive | Single Only |
MySQL | Sensitive | Single / Double |
SQLite | Sensitive | Single / Double |
DB2 | Sensitive | Single Only |
Oracle | Sensitive | Single Only |
SQL-92:
xxxxxxxxxx
WHERE UPPER(name) = UPPER('KaNyE')
MySQL:
xxxxxxxxxx
WHERE name = "KaNyE"
LIKE: is used for string matching.
'%' --> Matches any substring (include empty strings)
'_' --> Match any one character
xxxxxxxxxx
SELECT * FROM enrolled AS e
WHERE e.cid LIKE '15-%'
xxxxxxxxxx
SELECT * FROM student AS s
WHERE s.login LIKE '%@c_'
xxxxxxxxxx
SELECT name FROM student
WHERE login = LOWER(name) || '@cs'
But in MySQL use CONCAT()
xxxxxxxxxx
SELECT name FROM student
WHERE login = CONCAT(LOWER(name), '@cs')
SQL-92 & MySQL:
xxxxxxxxxx
SELECT NOW();
...
Store query results in another table:
SQL-92:
xxxxxxxxxx
SELECT DISTINCT cid INTO CourseIds
FROM enrolled;
MySQL:
xxxxxxxxxx
CREATE TABLE CourseIds (SELECT DISTINCT cid FROM enrolled);
Insert tuples from query into another table:
--> Inner SELECT must generate the same columns as the target table
SQL-92:
xxxxxxxxxx
INSERT INTO CourseIds
(SELECT DISTINCT cid FROM enrolled);
--> Order the output tuples by the values in one or more of their columns.
xxxxxxxxxx
SELECT sid, grade FROM enrolled
WHERE cid = '15-721'
ORDER BY grade
xxxxxxxxxx
SELECT sid, grade FROM enrolled
WHERE cid = '15-721'
ORDER BY 1
xxxxxxxxxx
SELECT sid FROM enrolled
WHERE cid = '15-721'
ORDER BY grade DESC, sid ASC
#3 Display ==>
xxxxxxxxxx
SELECT sid FROM enrolled
WHERE cid = '15-721'
ORDER BY grade DESC, 1 ASC
--> Limit the # of tuples return in output
--> Can set an offset to return a "range"
xxxxxxxxxx
SELECT sid, name FROM student
WHERE login LIKE '%@cs'
LIMIT 10
xxxxxxxxxx
SELECT sid, name FROM student
WHERE login LIKE '%@cs'
LIMIT 20 OFFSET 10
Queries containing other queries.
Inner queries can appear anywhere in query.
xxxxxxxxxx
SELECT name FROM student WHERE
sid IN (SELECT sid FROM enrolled)
inside ( ): Inner Query
outside ( ): Outer Query
Ex. Get the names of students in '15-445'
xxxxxxxxxx
SELECT name FROM student
WHERE sid IN(
SELECT sid FROM enrolled
WHERE cid = '15-445'
)
Nested Queries | Definition |
---|---|
ALL | Must satisfy expression for all rows in the sub-query |
ANY | Must satisfy expression for at least one row in the sub-query |
IN | Equivalent to ' = ANY( ) ' |
EXISTS | At least one row is returned |
Ex. Find all courses that have no students enrolled in it.
xxxxxxxxxx
SELECT * FROM student
WHERE NOT EXISTS(
SELECT * FROM enrolled
WHERE course.cid = enrolled.cid
)
Display ==>
--> ROW_NUMBER( ) -> # of the current row
--> RANK( ) -> Order position of the current row
xxxxxxxxxx
SELECT *, ROW_NUMBER() OVER () AS row_num
FROM enrolled
The OVER keyword specifies how to group togther tuples when computing the window function.
Use PATITION BY to specify group. (also can use ORDER BY)
xxxxxxxxxx
SELECT cid, sid,
ROW_NUMBER() OVER (PARTITION BY cid)
FROM enrolled
ORDER BY cid
Ex. Find the student with the second highest grade for each course.
xxxxxxxxxx
SELECT * FROM (
SELECT *, RANK() OVER (PARTITION BY cid
ORDER BY grade ASC) AS rank
FROM enrolled) AS ranking
WHERE ranking.rank = 2
Alternative to nested queries and views.
xxxxxxxxxx
WITH cteName (col1, col2) AS (
SELECT 1, 2
)
SELECT col1 + col2 FROM cteName
Ex. Find student record with the highest id that is enrolled in at least one course.
xxxxxxxxxx
WITH cteSource (maxId) AS (
SELECT MAX(sid) FROM enrolled
)
SELECT name FROM student, cteSourse
WHERE student.sid = cteSource.maxId
Ex. Print the sequence of numbers from 1 to 10
xxxxxxxxxx
WITH RECURSIVE cteSourse (counter) AS (
(SELECT 1)
UNION ALL
(SELECT counter + 1 FROM cteSource
WHERE counter < 10)
)
SELECT * FROM cteSource