-- 10/7 tee 2024_10_7_sql_log.txt use toyu SELECT DISTINCT s.major, s.stuId, CONCAT(s.fname, ' ', s.lname) AS student FROM student AS s WHERE s.major IN ('CSCI', 'CINF', 'ITEC'); SELECT DISTINCT 'ready to go in 4 minutes.', s.major, COUNT(s.stuId) AS numStudent, AVG(s.ach) AS `average ach` -- group functions, group by columns, constants FROM student AS s WHERE s.major IN ('CSCI', 'CINF', 'ITEC') GROUP BY s.major; GROUP_CONCAT([DISTINCT] expr [,expr ...] [ORDER BY {unsigned_integer | col_name | expr} [ASC | DESC] [,col_name ...]] [SEPARATOR str_val]) SELECT DISTINCT 'ready to go in 4 minutes.', s.major, COUNT(s.stuId) AS numStudent, AVG(s.ach) AS `average ach`, GROUP_CONCAT(CONCAT(s.fname, ' ', s.lname) ORDER BY s.lname ASC, s.fname ASC SEPARATOR "; ") AS students -- group functions, group by columns, constants FROM student AS s WHERE s.major IN ('CSCI', 'CINF', 'ITEC') GROUP BY s.major; SELECT DISTINCT 'ready to go in 4 minutes.', s.major, COUNT(s.stuId) AS numStudent, AVG(s.ach) AS `average ach`, GROUP_CONCAT(CONCAT(s.fname, ' ', s.lname) ORDER BY s.lname ASC, s.fname ASC SEPARATOR "; ") AS students -- group functions, group by columns, constants FROM student AS s WHERE s.major IN ('CSCI', 'CINF', 'ITEC') GROUP BY s.major HAVING `average ach` >= 40; SELECT DISTINCT 'ready to go in 4 minutes.', s.major, COUNT(s.stuId) AS numStudent, AVG(s.ach) AS `average ach`, GROUP_CONCAT(CONCAT(s.fname, ' ', s.lname) ORDER BY s.lname ASC, s.fname ASC SEPARATOR "; ") AS students -- group functions, group by columns, constants FROM student AS s WHERE s.major IN ('CSCI', 'CINF', 'ITEC') AND AVG(s.ach) >= 40 -- no group function here. GROUP BY s.major; ERROR 1111 (HY000): Invalid use of group function SELECT DISTINCT 'ready to go in 4 minutes.', s.major, COUNT(s.stuId) AS numStudent, AVG(s.ach) AS `average ach`, GROUP_CONCAT(CONCAT(s.fname, ' ', s.lname) ORDER BY s.lname ASC, s.fname ASC SEPARATOR "; ") AS students -- group functions, group by columns, constants FROM student AS s GROUP BY s.major HAVING s.minor IN ('CSCI', 'CINF', 'ITEC') AND `average ach` >= 40; ERROR 1054 (42S22): Unknown column 's.minor' in 'having clause' [2] Can you write a query to generate the following output? +----------+------------------------------+------------+----------+----------+ | deptCode | deptName | numFaculty | numMajor | numMinor | +----------+------------------------------+------------+----------+----------+ | ACCT | Accounting | 1 | 0 | 0 | | ARTS | Arts | 1 | 2 | 0 | | CINF | Computer Information Systems | 2 | 2 | 3 | | CSCI | Computer Science | 4 | 3 | 1 | | ENGL | English | 1 | 0 | 2 | | ITEC | Information Technology | 2 | 2 | 2 | | MATH | Mathematics | 0 | 0 | 0 | +----------+------------------------------+------------+----------+----------+ 7 rows in set (0.00 sec) -- [2a] columns 1 and 4. SELECT DISTINCT s.major, COUNT(s.stuId) AS numMajor FROM student AS s GROUP BY s.major; SELECT DISTINCT s.major, COUNT(s.stuId) AS numMajor FROM department AS d INNER JOIN student AS s ON (d.deptCode = s.major) GROUP BY s.major; SELECT DISTINCT s.major, COUNT(s.stuId) AS numMajor FROM department AS d LEFT JOIN student AS s ON (d.deptCode = s.major) GROUP BY s.major; SELECT DISTINCT d.deptCode, COUNT(s.stuId) AS numMajor FROM department AS d LEFT JOIN student AS s ON (d.deptCode = s.major) GROUP BY d.deptCode; -- [2b] columns 1 and 5. SELECT DISTINCT d.deptCode, COUNT(s.stuId) AS numMinor FROM department AS d LEFT JOIN student AS s ON (d.deptCode = s.minor) GROUP BY d.deptCode; -- [2c] columns 1 and 3. SELECT DISTINCT d.deptCode, COUNT(f.facId) AS numFaculty FROM department AS d LEFT JOIN faculty AS f ON (d.deptCode = f.deptCode) GROUP BY d.deptCode; -- [2] WITH t1 AS (SELECT DISTINCT d.deptCode, COUNT(f.facId) AS numFaculty FROM department AS d LEFT JOIN faculty AS f ON (d.deptCode = f.deptCode) GROUP BY d.deptCode), t2 AS (SELECT DISTINCT d.deptCode, COUNT(s.stuId) AS numMajor FROM department AS d LEFT JOIN student AS s ON (d.deptCode = s.major) GROUP BY d.deptCode), t3 AS (SELECT DISTINCT d.deptCode, COUNT(s.stuId) AS numMinor FROM department AS d LEFT JOIN student AS s ON (d.deptCode = s.minor) GROUP BY d.deptCode) SELECT d.deptCode, d.deptName, t1.numFaculty, t2.numMajor, t3.numMinor FROM department AS d INNER JOIN t1 USING (deptCode) INNER JOIN t2 USING (deptCode) INNER JOIN t3 USING (deptCode); WITH temp AS (SELECT DISTINCT sc.schoolName AS college, d.deptName AS department, COUNT(s.stuId) As deptMajor FROM school AS sc INNER JOIN department AS d ON (sc.schoolCode = d.schoolCode) LEFT JOIN student AS s ON (s.major = d.deptCode) GROUP BY college, department) SELECT temp.college, temp.department, temp.deptMajor AS `major in department`, SUM(deptMajor) OVER(PARTITION BY college) AS `major in college`, SUM(deptMajor) OVER() AS `major in university` FROM temp; -- 10/2 SELECT stuId FROM enroll; SELECT DISTINCT stuId FROM enroll; SELECT DISTINCT f.facId, f.lname FROM faculty AS f WHERE rank = 'Professor'; SELECT DISTINCT f.facId, f.lname WHERE rank = 'Professor' FROM faculty AS f; DROP SCHEMA IF EXISTS tinker; CREATE SCHEMA tinker; USE tinker; CREATE TABLE s2 -- creation + population. SELECT * FROM toyu.student; SELECT * FROM s2; CREATE TEMPORARY TABLE s3 SELECT * FROM toyu.student; SELECT * FROM s3; -- CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name -- { LIKE old_tbl_name | (LIKE old_tbl_name) } CREATE TABLE s4 LIKE toyu.student; -- creation of table SELECT * FROM s4; INSERT INTO s4 -- population. SELECT * FROM toyu.student; SELECT * FROM s4; SHOW TABLES; -- Note that keys and constraints of student are missing in s2 and S3. DESC toyu.student; DESC s2; DESC s4; DESC s3; DROP TABLE s2; DROP TABLE s3; DROP TABLE s4; SHOW TABLES; DROP SCHEMA IF EXISTS tinker; UPDATE [LOW_PRIORITY] [IGNORE] table_reference SET assignment_list [WHERE where_condition] [ORDER BY ...] [LIMIT row_count] UPDATE Student SET major = 'ITEC' WHERE StuId = 100000; UPDATE Student SET major = 'CSCI'; -- student with credits in a range. SELECT DISTINCT * FROM Student WHERE ach BETWEEN 30 AND 70; SELECT DISTINCT * FROM Student WHERE ach BETWEEN 35 AND 66; -- student with credits in a range. SELECT DISTINCT * FROM Student WHERE ach>= 30 AND ach <= 70; SELECT DISTINCT s.fname, s.lname, c.classId, e.grade FROM student AS s, enroll AS e, class AS c WHERE s.stuId = e.stuId -- Join condition AND e.classId = c.classId -- Join condition AND c.semester = 'Fall' -- problem condition AND c.year = 2019; -- problem condition SELECT DISTINCT s.fname, s.lname, c.classId, e.grade FROM student AS s INNER JOIN enroll e ON (s.stuId = e.stuId) -- Join condition INNER JOIN class AS c ON (e.classId = c.classId) -- Join condition WHERE c.semester = 'Fall' -- Problem condition AND c.year = 2019; -- Problem condition -- List the names of the students with their minors (in full name). -- Student with no department not listed. SELECT DISTINCT CONCAT(s.fname, ' ', s.lname) AS student, d.deptName AS `minor department` FROM student AS s INNER JOIN department AS d ON (s.minor = d.deptCode); SELECT DISTINCT CONCAT(s.fname, ' ', s.lname) AS student, d.deptName AS `minor department` FROM student AS s LEFT JOIN department AS d ON (s.minor = d.deptCode); SELECT DISTINCT CONCAT(s.fname, ' ', s.lname) AS student, IFNULL(d.deptName, 'Undeclared') AS `minor department` FROM student AS s LEFT JOIN department AS d ON (s.minor = d.deptCode); -- subqueries in the WHERE course -- students not enrolled in any class. SELECT DISTINCT * FROM student AS s WHERE s.stuId NOT IN (SELECT DISTINCT e.stuID FROM enroll AS e); -- student with the maximum number of ach. SELECT DISTINCT MAX(ach) -- group function FROM student; -- CTE WITH t1 AS (SELECT MAX(ach) AS max FROM student) SELECT s.stuId, s.ach AS `ach credits`, t1.max - s.ach AS `diff from max credits of all` FROM student AS s, t1 ORDER BY `ach credits` DESC; -- student within 60 credits of the maximum number of ach any student may have. SELECT DISTINCT s.stuId, CONCAT(s.fname, ' ', s.lname) AS student, s.ach AS credits FROM student AS s WHERE s.ach + 60 >= (SELECT DISTINCT MAX(ach) FROM student); -- implicit type converstion: a table -> a number: 125 -- subqueries as derived tables. SELECT DISTINCT s.stuId, CONCAT(s.fname, ' ', s.lname) AS student, s.ach AS credits FROM student AS s INNER JOIN (SELECT DISTINCT MAX(ach) AS max FROM student) AS m -- an alias is required. WHERE s.ach + 60 >= m.max; -- CTE WITH m AS -- step [1] (SELECT DISTINCT MAX(ach) AS max FROM student) SELECT DISTINCT s.stuId, CONCAT(s.fname, ' ', s.lname) AS student, s.ach AS credits FROM student AS s INNER JOIN m WHERE s.ach + 60 >= m.max; -- CTE WITH t1 AS (SELECT MAX(ach) AS max FROM student) SELECT s.stuId, s.ach AS `ach credits`, t1.max - s.ach AS `diff from max credits of all` FROM student AS s, t1 ORDER BY `ach credits` DESC; -- CTE solution WITH t1 AS -- Common table scope: just the current SQL statement. -- scope should be as small as possible. (SELECT MAX(ach) AS max FROM student), t2 AS (SELECT s.stuId, s.ach AS `ach credits`, t1.max - s.ach AS diff, s.major FROM student AS s, t1) SELECT t2.stuId, t2.`ach credits`, t2.diff AS `diff from max credits of all`, d.deptName AS department FROM t2 LEFT JOIN department d ON (t2.major = d.deptCode) ORDER BY t2.`ach credits` DESC; -- t1 and t2 no longer defined. -- temporary tables; -- scope: client session CREATE TEMPORARY TABLE tt1 AS SELECT MAX(ach) AS max FROM student; SELECT * FROM tt1; CREATE TEMPORARY TABLE tt2 AS SELECT s.stuId, s.ach AS `ach credits`, tt1.max - s.ach AS diff, s.major FROM student AS s, tt1; SELECT * FROM tt2; SELECT tt2.stuId, tt2.`ach credits`, tt2.diff AS `diff from max credits of all`, d.deptName AS department FROM tt2 LEFT JOIN department d ON (tt2.major = d.deptCode) ORDER BY tt2.`ach credits` DESC; DROP SCHEMA IF EXISTS CTEtinker; CREATE SCHEMA CTETinker; USE SCHEMA CTEtinker; CREATE OR REPLACE TABLE Employee ( EmpId CHAR(7) NOT NULL, SupervisorEmpId CHAR(7) NULL, CONSTRAINT Emp_EmpId_pk PRIMARY KEY (EmpId), CONSTRAINT Emp_SupervisorEmpId_fk FOREIGN KEY (SupervisorEmpId) REFERENCES Employee(EmpId) ); INSERT INTO Employee(EmpId, SupervisorEmpId) VALUES ('E3', null); INSERT INTO Employee(EmpId, SupervisorEmpId) VALUES ('E15', 'E3'); INSERT INTO Employee(EmpId, SupervisorEmpId) VALUES ('E50', 'E15'); INSERT INTO Employee(EmpId, SupervisorEmpId) VALUES ('E75', 'E50'); INSERT INTO Employee(EmpId, SupervisorEmpId) VALUES ('E100', 'E75'); INSERT INTO Employee(EmpId, SupervisorEmpId) VALUES ('E102', 'E75'); INSERT INTO Employee(EmpId, SupervisorEmpId) VALUES ('E70', 'E50'); INSERT INTO Employee(EmpId, SupervisorEmpId) VALUES ('E103', 'E70'); SELECT * FROM Employee; -- supervisor of 'E100' SELECT DISTINCT SupervisorEmpId FROM Employee WHERE EmpId = 'E100'; -- All (direct/indirect supervisor of E100: E75, E50, E15, E3. WITH RECURSIVE Super(SEId) AS ( SELECT SupervisorEmpId AS SEId FROM Employee AS e WHERE e.EmpId = 'E100' -- initial condition/action -- init: Super: E75 UNION ALL -- union all: add rows created by the recursive action to the result, table Super. SELECT e.SupervisorEmpId AS SEId -- recursive action FROM Employee AS e INNER JOIN Super WHERE e.EmpId = Super.SEId AND e.SupervisorEmpId IS NOT NULL -- negation of exit condition. -- exit condition: when the recursive action returns an empty table. ) SELECT * FROM Super; SELECT DISTINCT s.major, s.stuId, s.ach FROM student AS s WHERE s.major IN ('CSCI', 'CINF', 'ITEC'); -- Bad meaning but MySQL allows it. SELECT DISTINCT s.major, s.stuId, s.ach FROM student AS s WHERE s.major IN ('CSCI', 'CINF', 'ITEC') GROUP BY s.major; SELECT DISTINCT 'ready to go in 4 minutes.', s.major, COUNT(s.stuId) AS numStudent, AVG(s.ach) AS `average ach` -- group functions, group by columns, constants FROM student AS s WHERE s.major IN ('CSCI', 'CINF', 'ITEC') GROUP BY s.major;