SQL (cont’d) CSE3330 Spring 2014 Chengkai Li. NULL values.
-
Upload
esmond-hamilton -
Category
Documents
-
view
219 -
download
0
Transcript of SQL (cont’d) CSE3330 Spring 2014 Chengkai Li. NULL values.
SQL (cont’d)
CSE3330Spring 2014Chengkai Li
NULL values
NULL values are all different
The following query looks for employees who earn the same as their supervisors. If the database does not contain salary information of an employee and the supervisor (null values), the employee doesn’t appear in query result. (Which is what we shall expect.)
SELECT E1.fname, E1.lnameFROM EMPLOYEE AS E1, EMPLOYEE AS E2WHERE E1.superssn=E2.ssnAND E1.salary= E2.salary;
Except that NULL values are all equal in UNION/INTERSECT/EXCEPT/DISTINCT/GROUP BY
SELECT COUNT(*) FROM ( SELECT E.superssn FROM EMPLOYEE AS E, DEPARTMENT AS D WHERE E.dno=D.dnumber AND D.dname=‘research’ INTERSECT SELECT E.superssn FROM EMPLOYEE AS E, WORKS_ON AS W WHERE E.ssn=W.essn AND W.hours > 30 ) AS T;
EMPLOYEE DEPARTMENT WORKS_ONssn superssn dno dnumber dname essn proj hours--------------------------------- ------------------------------ -------------------------- 111 NULL 1 1 research 111 1 20112 NULL 2 2 sales 112 2 35 113 111 1 113 1 35
Except that NULL values are all equal in UNION/INTERSECT/EXCEPT/DISTINCT/GROUP BY
All employees with “null” salary values belong to a group.
SELECT salary, COUNT(*)FROM EMPLOYEEGROUP BY salary;
Aggregation• Take out null values, before aggregates are calculated.
(except COUNT(*))• Suppose there are null values in “salary”.
SELECT AVG(salary) FROM EMPLOYEE;is different from
SELECT SUM(salary)/COUNT(*) FROM EMPLOYEE;
SELECT COUNT(salary) FROM EMPLOYEE;is different from
SELECT COUNT(*) FROM EMPLOYEE;
The confusing DISTINCT (at least in MySQL)
• SELECT a, b FROM T;
a b ----------- 1 1 2 NULL 2 NULL
• SELECT DISTINCT a, b FROM T;
a b ----------- 1 1 2 NULL
• SELECT COUNT (DISTINCT a, b) FROM T;
COUNT (DISTINCT a, b) -------------------------------- 1
NULL values are all equal in DISTINCT, without COUNT. They are ignored in COUNT (DISTINCT …)
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
8
Subqueries
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
9
Subqueries
A parenthesized SELECT statement (subquery) in another SELECT statement.
Can be in FROM clause
Can be in WHERE clause
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Subquery in FROM• In place of a relation in the FROM clause, we can place another query, and
then query its result.
• use a tuple-variable to name tuples of the result.
• Subquery in FROM is not mentioned in textbook, but is useful.
• The SQL syntax on page 140 needs revision to include subquery in FROM
SELECT
FROM ( SELECT ...
FROM …
[WHERE …]
[ GROUP BY …
[HAVING …] ]
[ORDER BY …]
) AS …
[WHERE …] [ GROUP BY … [HAVING …]] [ORDER BY …]
10
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
ExampleSELECT S.sid, S.name, R.semester, R.year
FROM students AS S,
( SELECT *
FROM register
WHERE grade=‘A’
) AS R
WHERE S.sid=R.sid
SELECT MAX(total)
FROM ( SELECT sid, COUNT(*) as total
FROM register
GROUP BY sid
) AS R11
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Subquery in WHERE
Subqueries in WHERE are also called nested queries
INEXISTS> / < / = / >= / <= / < > ANY/ALL
12
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
SELECT statements embedded in other statements
UNION, INTERSECT, EXCEPT
Q4: (SELECT PNAMEFROM PROJECT, DEPARTMENT, EMPLOYEEWHERE DNUM=DNUMBER AND
MGRSSN=SSN AND LNAME='Smith')
UNION
(SELECT PNAMEFROM PROJECT, WORKS_ON, EMPLOYEEWHERE PNUMBER=PNO AND
ESSN=SSN AND LNAME='Smith')
13
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Correlated SubqueriesSubqueries in FROM must not be correlated
SELECT *
FROM Dependents AS D,
( SELECT *
FROM Employee AS E
WHERE E.SSN=D.ESSN
) AS R
Nested queries (Subqueries in WHERE) can be correlated
14
Copyright © 2011 Pearson Education, Inc. Publishing as Pearson Addison-Wesley
Nested Queries can be deep
SELECT PNO
FROM WORKS_ON
WHERE ESSN IN
(SELECT SSN
FROM EMPLOYEE
WHERE LNAME=‘Smith’
AND
DNO IN (SELECT DNUMBERFROM DEPARTMENTWHERE DNAME= ‘Research’) );
15
MySQL doesn’t provide EXCEPT/MINUS and INTERSECT
• A nice write-up at http://faculty.utpa.edu/chebotkoa/main/teaching/csci4333fall2013/slides/MySQL-set-operators.pdf
• However, complexity due to null value is not considered.
• Bag semantics is not considered either.
Rewrite EXCEPT and INTERSECTSELECT ssn FROM EMPLOYEE WHERE salary < 10000 EXCEPT SELECT essn FROM WORKS_ON WHERE hours > 30;
Rewrite this query using IN, EXISTS, LEFT OUTER JOIN
Rewrite EXCEPT by INSELECT ssn FROM EMPLOYEE WHERE salary < 10000 EXCEPT SELECT essn FROM WORKS_ON WHERE hours > 30;
SELECT ssn FROM EMPLOYEE WHERE salary < 10000AND ssn NOT IN (SELECT essn FROM WORKS_ON WHERE hours > 30);
Rewrite EXCEPT by EXISTSSELECT ssn FROM EMPLOYEE WHERE salary < 10000 EXCEPT SELECT essn FROM WORKS_ON WHERE hours > 30;
SELECT ssn FROM EMPLOYEE WHERE salary < 10000AND NOT EXISTS (SELECT essn FROM WORKS_ON WHERE hours > 30 AND essn=ssn);
Rewrite EXCEPT by LEFT OUTER JOINSELECT ssn FROM EMPLOYEE WHERE salary < 10000 EXCEPT SELECT essn FROM WORKS_ON WHERE hours > 30;
Incorrect rewriting: SELECT ssn FROM EMPLOYEE LEFT OUTER JOIN WORKS_ON ON ssn=essnWHERE salary < 10000 AND hours <= 30;
WORKS_ON EMPLOYEEessn pno hours ssn salary------------------------- ---------------------111 1 31 111 5000111 2 9
Rewrite EXCEPT by LEFT OUTER JOINCorrect rewriting: SELECT ssn FROM ((SELECT ssn FROM EMPLOYEE WHERE salary < 10000) AS R LEFT OUTER JOIN (SELECT essn FROM WORKS_ON WHERE hours > 30) AS T ON R.ssn=T.essn)WHERE T.essn IS NULL;
WORKS_ON EMPLOYEE R T R left outer join Tessn pno hours ssn salary ssn essn ssn essn------------------------- --------------------- ------- ------- --------------------------111 1 31 111 5000 111 111 111 111111 2 9 112 8000 112 112 112 1 20