Presentation is loading. Please wait.

Presentation is loading. Please wait.

More SQL Nested and Union queries, and more

Similar presentations


Presentation on theme: "More SQL Nested and Union queries, and more"— Presentation transcript:

1 More SQL Nested and Union queries, and more
iSQLplus: More SQL Nested and Union queries, and more For most queries, we use the same sample data as before: Personnel, Branch, Transport tables. Reading: For example: Connolly/Begg (4th Ed) : / / / 5.3.9 Any SQL book!!! November 18

2 XY XY XY YX X Y X Y X Y X Y
SQL2 November 18 Match up the set operations, diagrams and SQL words XY XY XY YX a. b. c. d. i. UNION ii. MINUS iii. INTERSECT iv. EXCEPT Y X X Y X Y Note: EXCEPT and MINUS do the same thing. EXCEPT is standard SQL, MINUS is Oracle dialect. Access has only UNION implemented. X Y

3 Set operations in SQL Set operations are union (), intersect (), set difference () Oracle SQL has corresponding operators UNION, INTERSECT, MINUS (standard SQL: EXCEPT) use these to “glue together” two SELECT statements with union-compatible results Can combine several using brackets like in maths by default deletes duplicates - use UNION ALL to keep them in November 18

4 Example Reader Staff Student Library readers
{optional, and} Staff Student Library readers each reader can be staff, student, both, or neither Stored in three relations: Reader(readerNo, name, address) contains all readers. staff also have a record in Staff, students in Student Staff(readerNo*, department, ) Student(readerNo*,matricNo, course, ) November 18

5 Example: INTERSECT Find all readers who are both staff and student
Reader(readerNo, name, address) Staff(readerNo, department, ) Student(readerNo,matricNo, course, ) Example: INTERSECT Find all readers who are both staff and student SQL: No semi-colon at end of first SELECT. Why? SELECT ReaderNo FROM Staff INTERSECT SELECT ReaderNo FROM Student; November 18

6 Example: MINUS SELECT ReaderNo FROM Reader
SQL2 November 18 Reader(readerNo, name, address) Staff(readerNo, department, ) Student(readerNo,matricNo, course, ) Example: MINUS Find all readers who are not students SQL: SELECT ReaderNo FROM Reader MINUS SELECT ReaderNo FROM Student; To get names is difficult if not impossible with this query structure. You might try SELECT ReaderNo, name FROM Reader MINUS SELECT ReaderNo FROM Student; but this would not work because not the same columns, so not union-compatible. But student does not have a name field, so could not add it there. Would be much better to use NOT IN instead. How could you change this to get the names as well? November 18

7 Reminder: Basic SQL SELECT <attributes> FROM <Tables>
May include aliases and aggregate functions FROM <Tables> List Tables and may use Join operations WHERE <condition> Use logical expressions and may Join tables GROUP BY <aggregate statistics> HAVING <aggregate condition> ORDER BY <sorting attributes> November 18

8 Using IS NULL To find missing/empty values use IS NULL
To exclude them use IS NOT NULL Useful in LEFT / RIGHT / FULL JOINS to find values that don't have a match SELECT * FROM personnel WHERE bonus IS NULL; SELECT * FROM personnel WHERE bonus IS NOT NULL; Query 2-1.sql Query 2-2.sql Note: NULL is different from 0!!!!! November 18

9 Reminder Example “Find staff outside London who don't have a company car” SELECT surname, city FROM personnel p LEFT JOIN transport t ON p.snum=t.snum, branch b WHERE city <> 'LONDON' AND t.snum IS NULL AND p.div = b.div; Query 2-3.sql Hints: How many tables are required by the query? Remember to join the tables November 18

10 Nested Queries Queries can be used within other queries
usually in WHERE clause can also be in HAVING clause or used in calculated columns in SELECT expression in WHERE compares value with a query result uses math operators =, >, <, >=, <=, <> and keywords ALL, ANY, IN, NOT IN, EXISTS, NOT EXISTS November 18

11 Example 1 SELECT Regno, make FROM transport WHERE mileage <
SQL2 November 18 Example 1 Find cars whose mileage is less than the Jaguar's. Two steps: Find mileage of the Jaguar Compare other mileages with that one Nested query (subquery) does all of this. Query 2-4.sql SELECT Regno, make FROM transport WHERE mileage < (SELECT mileage FROM transport WHERE make='JAGUAR'); Danger! This only works if the subquery returns a single value! November 18

12 SQL2 November 18 Example 2 Find staff with lower than average salaries, and show how much lower they are SELECT snum, surname, salary-(SELECT AVG(salary)FROM personnel) AS difference FROM Personnel p WHERE salary < (SELECT AVG(salary) FROM personnel); Query 2-5.sql Note: need the subqueries because aggregate functions are not allowed in WHERE and cannot be mixed with non-aggregates in SELECT November 18

13 Nested Queries : Operators
If sub-query can return more than one result use an operator in the comparison (IN, NOT IN, ANY, ALL, EXISTS, NOT EXISTS) IN compares a value with a set and evaluates to True if the value is in the set and False otherwise set can be a query result or a simple set, e.g. WHERE town IN ('Dundee', 'Perth', 'Aberdeen') NOT IN November 18

14 Nested Queries: more operators
ANY at least one result of the subquery must fulfil the condition ALL all results of the subquery must fulfil the comparison EXISTS returns True if there is at least one tuple in the subquery and False otherwise NOT EXISTS checks for empty sub-query November 18

15 Nested Examples: IN, ANY
Find all staff working in London SELECT snum, surname FROM personnel WHERE div IN (SELECT div FROM branch WHERE city='LONDON'); or WHERE div = ANY Query 2-6.sql Query 2-7.sql November 18

16 Find staff earning more than those in branch 30
SQL2 November 18 Find staff earning more than those in branch 30 A SELECT * FROM personnel WHERE div <> 30 and salary > (SELECT salary FROM personnel WHERE div=30); B SELECT * FROM personnel WHERE div != 30 and salary > ANY (SELECT salary FROM personnel WHERE div=30); C SELECT * FROM personnel WHERE div <> 30 and salary > ALL (SELECT salary FROM personnel WHERE div=30); A will not run, because the subquery returns more than one value, so > is not a valid comparison operator. B will run, and returns staff not in branch 30 who earn more than someone (anyone) in branch 30; i.e. they earn more than AT LEAST ONE PERSON FROM BRANCH 30. C will run, and returns staff not in branch 30 who earn more than EVERYONE in branch 30; i.e. they earn more than EACH AND EVERY PERSON FROM BRANCH 30. So, I would regard C as correct (and this is script 2-8.sql). However, the question is actually not phrased very precisely, so B could also be regarded as correct. D Both A and C are correct Query 2-8.sql

17 Nested Examples: ALL SELECT * FROM branch WHERE div <> ALL
branches which don’t have a director SELECT * FROM branch WHERE div <> ALL (SELECT div FROM personnel WHERE jobtitle = 'DIRECTOR'); Query 2-9.sql Note: no space between < and > November 18

18 How did this work? Subquery produces the result
Outer Query takes this result and produces a list of branches which are none of these i.e. 20 10 30 40 50 November 18

19 Remember to specify join criterion
EXISTS / NOT EXISTS branches which have no staff SELECT * FROM branch WHERE NOT EXISTS (SELECT * FROM personnel p WHERE p.div = branch.div); Query sql Remember to specify join criterion November 18

20 How did it work? DBMS evaluates sub-query separately for each value of p.div If sub-query result is empty, NOT EXISTS is true, so this branch is in the result of the main query If p.div=branch.div is omitted, sub-query is evaluated for all branches at once, sub-result not empty, so main query returns nothing November 18

21 Which of these queries also find branches with no staff?
SQL2 November 18 Which of these queries also find branches with no staff? A SELECT * FROM branch MINUS SELECT div FROM personnel; Query 2-11a.sql B SELECT b.* FROM personnel p RIGHT JOIN branch b ON p.div=b.div WHERE b.div IS NULL; Query 2-11b.sql C SELECT * FROM branch WHERE div NOT IN (SELECT div FROM personnel); The ideas used for all queries are all fine and are all equivalent, but: A gives error as columns not union-compatible. Would be ok if * is replaced by div. B returns no results as b.div is the wrong column to apply NULL criterion to. Replace b.div IS NULL with p.div IS NULL. C is correct. Query 2-11c.sql D Both B and C are correct but A is not E All queries are correct

22 Back to the start SELECT ReaderNo FROM Reader
SQL2 November 18 Reader(readerNo, name, address) Staff(readerNo, department, ) Student(readerNo,matricNo, course, ) Back to the start Find all readers who are not students SQL: SELECT ReaderNo FROM Reader MINUS SELECT ReaderNo FROM Student; To get names is difficult if not impossible with this query structure. You might try SELECT ReaderNo, name FROM Reader MINUS SELECT ReaderNo FROM Student; but this would not work because not the same columns, so not union-compatible. But student does not have a name field, so could not add it there. Would be much better to use NOT IN instead. So now, write another query that will find the readerno and name of all readers who are not students. November 18

23 Summary Basic SQL SELECT Advanced SQL SELECT Basic query facilities
SELECT FROM WHERE GROUP BY HAVING ORDER BY IS NULL / IS NOT NULL Advanced SQL SELECT Nested Queries ALL, ANY, EXISTS, NOT EXISTS, IN, NOT IN Set operators UNION, INTERSECT, MINUS November 18


Download ppt "More SQL Nested and Union queries, and more"

Similar presentations


Ads by Google