Chapter 12 Subqueries and Merge Statements (up to p.451) Jason C. H. Chen, Ph.D. Professor of MIS School of Business Gonzaga University Spokane, WA 99258 USA chen@jepson.gonzaga.edu Dr. Chen, Oracle Database System (Oracle) 1 FOCUS – most of them have been studied • Three topics (Learn up to p. 451): – Single-Row subquery • Subquery returns “single” value – Multiple-Row subquery • Subquery returns “multiple” values – Multiple-Column subquery • For “matching” return values on different subjects • • • • We will focus on the following: Single-Row Subquery in a HAVING Clause (Query#4) Multiple-Row Subquery in “IN” (Query#7) Multiple-Column Subquery in a FROM Clause (Query#11 – revisit Query#7) Dr. Chen, Oracle Database System (Oracle) 2 Objectives • Determine when using a subquery is appropriate • Identify which clauses can contain subqueries • Distinguish between an outer query and a subquery • Use a single-row subquery in a WHERE clause • Use a single-row subquery in a HAVING clause • Use a single-row subquery in a SELECT clause • Distinguish between single-row and multiple-row comparison operators • Use a multiple-row subquery in a WHERE clause Dr. Chen, Oracle Database System (Oracle) 3 Objectives (continued) • Use a multiple-row subquery in a HAVING clause • Use a multiple-column subquery in a WHERE clause • Create an inline view using a multiple-column subquery in a FROM clause • Compensate for NULL values in subqueries • Distinguish between correlated and uncorrelated subqueries • Nest a subquery inside another subquery • Use a subquery in a DML action • Process multiple DML actions with a MERGE statement Dr. Chen, Oracle Database System (Oracle) 4 Refresh the Database • 1. Run the following script file – Start c:\oradata\chapter12\JLDB_Build_12.sql Dr. Chen, Oracle Database System (Oracle) 5 Creating Nested Queries • Used to select results based on the result of a query • Consists of a main query and one or more subqueries. – Main/outer query: first query that appears in the SELECT command – Subquery retrieves values that the main query’s search condition must match Dr. Chen, Oracle Database System (Oracle) that return thatvalue return one one value 6 Subqueries and Their Rules/Uses Subquery – a query nested inside another query and used when a query is based on an unknown value. • A subquery must be complete query in itself – it requires SELECT and FROM clauses • A subquery, except one in the FROM clause, can’t have an ORDER BY clause (on the outer query’s last clause). • Must be enclosed in parentheses to separate it from the outer/main query • Place on right side of comparison operator Dr. Chen, Oracle Database System (Oracle) 7 Types of Subqueries Table 12-1 Topics Covered in This Chapter Dr. Chen, Oracle Database System (Oracle) 8 I. Single-Row Subqueries • Can only return one result to the outer query • Operators include =, >, <, >=, <=, < > Dr. Chen, Oracle Database System (Oracle) 9 Query: List all computer books with a retail price higher than the book “Database Implementation” First, find out the “cost” of book “Database Implementation” Next, plug in the “found cost” into the second query Figure 12-3 A single-row subquery Dr. Chen, Oracle Database System (Oracle) -- chapter 12, Figure 12-2; p.430 SELECT category, title, cost FROM books WHERE cost > 31.4 AND category = 'COMPUTER'; 10 Single-Row Subquery in a WHERE Clause Query1: List all computer books with a retail price higher than the book “Database Implementation” Subquery – a query nested inside another query and used when a query is based on an unknown value. -- chapter 12, Figure 12-3; p.431 SELECT category, title, cost FROM books WHERE cost > (SELECT cost FROM books WHERE title = 'DATABASE IMPLEMENTATION’) AND category = 'COMPUTER' Dr. Chen, Oracle Database System (Oracle) Only one value should be returned from the inner query 11 Query2: List title of the most expensive book sold by JustLee Books (incorrect example) Figure 12-4 Flawed query: attempt to determine the book with the highest retail value Dr. Chen, Oracle Database System (Oracle) 12 Query2: List title of the most expensive book sold by JustLee Books (a correct example) SELECT title, retail FROM books WHERE retail = (SELECT MAX(retail) FROM books); Dr. Chen, Oracle Database System (Oracle) Figure 12-5 Query to determine the title of the most expensive book 13 Query3: List title of all books published by publisher of ‘Big Bear and Little Dove’ that generate more than the average profit Tasks: two unknown values: 1) the pubid of ‘Big Bear and Little Dove’, 2) the average profit of the all books. SELECT isbn, title FROM books WHERE pubid = (SELECT pubid FROM books WHERE title = 'BIG BEAR AND LITTLE DOVE') AND retail-cost > (SELECT AVG(retail-cost) FROM books); Dr. Chen, Oracle Database System (Oracle) Figure 12-6 SELECT statement with two singlerow subqueries 14 Query4: List all book categories returning a higher average profit than the ‘Literature’ category. Three steps are needed for this task: • 1. calculate the average profit for all ‘Literature’ books. • 2. calculate the average profit for each category. • 3. compare the average profit for each category with the average profit for the ‘Literature’ category. Dr. Chen, Oracle Database System (Oracle) 15 Single-Row Subquery in a HAVING Clause Query4: List all book categories returning a higher average profit than the ‘Literature’ category. • Required when returned value is compared to grouped data #2 #3 Figure 12-7 Dr. Chen, Oracle Database System (Oracle) #1 Single-row subquery nested in a HAVING clause 16 Single-Row Subquery in a SELECT Clause Query5: Compare the price of each book in inventory against average price of all books in inventory. • Replicates subquery value for each row displayed Figure 12-8 Single-row subquery in a SELECT clause Dr. Chen, Oracle Database System (Oracle) 17 Single-Row Subquery in a SELECT Clause (coni.) Query6: List the difference between each book price and the average. • Replicates subquery value for each row displayed Figure 12-9 Use a subquery in a calculation in the SELECT clause Dr. Chen, Oracle Database System (Oracle) 18 II. Multiple-Row Subqueries • Return more than one row of results • Require use of IN, ANY, ALL, or EXISTS operators Dr. Chen, Oracle Database System (Oracle) 19 ANY and ALL Operators • Combine with arithmetic operators Table 12-2 ALL and ANY Operator Combinations Dr. Chen, Oracle Database System (Oracle) 20 Multiple-Row Subquery in a WHERE Clause Query7: List book titles, retail value and category that match the highest retail value for any book category 1. Determine the price of the most expensive book in each category 2. The maximum retail price in each category is to the WHERE clause of the outer query (more than one) 3. The outer query compares each book’s price to the prices from #2 4. If a book’s rail price matches one of the prices returned, the book’s title, retail price, and category are displayed in the output -- chapter 12, Figure 12-10; p.438 SELECT title, retail, category FROM books WHERE retail IN (SELECT MAX(retail) # this part will FROM books be executed first GROUP BY category) ORDER BY category; Dr. Chen, Oracle Database System (Oracle) Note: Could use IN operator or =ANY 21 Multiple-Row Subquery in a WHERE Clause SQL> SELECT MAX(retail) 2 FROM books 3 GROUP BY category; MAX(RETAIL) ----------75.95 28.75 59.95 39.95 31.95 30.95 89.95 29.95 Figure 12-10 Multiple-row subquery with the IN operator Dr. Chen, Oracle Database System (Oracle) 8 rows selected. 22 Multiple-Row Subquery in a WHERE Clause Q: what might be a problem on this query? A: retail might match “MAX” from a different category. Q: how to solve the problem? Figure 12-10 Multiple-row subquery with the IN operator Dr. Chen, Oracle Database System (Oracle) A: Use “Multiplecolumn” subquery (see next session). 23 Multiple-Row Subquery in a WHERE Clause (cont.) Query8: List all books with a retail price less than the most expensive book in the Cooking category. Practice other examples with >ALL, <ALL and >ANY Figure 12-14 Dr. Chen, Oracle Database System (Oracle) Using <ANY operator 24 Multiple-Row Subquery in a HAVING Clause Query9: Check whether any customer’s recently placed order has a total amount due greater than the total amount due for every order placed recently by customers in Florida. Q: try to use “ANY” and see the result. ---SUBQUERY SELECT SUM( quantity*paideach) FROM customers JOIN orders USING (customer#) JOIN orderitems USING (order#) WHERE state = 'FL' GROUP BY order#; SUM(QUANTITY*PAIDEACH) ---------------------106.85 85.45 54.5 17.9 Figure 12-17 Multiple-row subquery in a HAVING clause Oracle Database System (Oracle) 75.9 Highest Dr. Chen, 25 ---SUBQUERY SQL> SELECT order#, SUM( quantity * paideach) SELECT SUM( quantity*paideach) 2 FROM orderitems FROM customers JOIN orders USING (customer#) 3 HAVING SUM( quantity * paideach) > JOIN orderitems USING (order#) 4 ANY (SELECT SUM( quantity * paideach) WHERE state = 'FL' GROUP BY order#; 5 FROM customers JOIN orders USING (customer#) SUM(QUANTITY*PAIDEACH) 6 JOIN orderitems USING (order#) ---------------------7 WHERE state = 'FL' 106.85 8 GROUP BY order#) 85.45 Lowest 54.5 9 GROUP BY order#; 17.9 75.9 ORDER# SUM(QUANTITY*PAIDEACH) ---------- ---------------------1000 19.95 -- continued from last page 1001 117.4 ORDER# SUM(QUANTITY*PAIDEACH) 1002 111.9 ---------- ---------------------1003 106.85 1011 85.45 1004 170.9 1012 166.4 1005 39.95 1013 55.95 1006 54.5 1014 44 1007 335.85 1015 19.95 1008 39.9 1016 85.45 1009 41.95 1018 75.9 1010 55.95 1019 22 1020 19.95 Dr. Chen, Oracle Database System (Oracle) 26 III. Multiple-Column Subqueries • Return more than one column in results • Creates a temporary table (or inline view) • Can return more than one column to the outer query (more than one column from the subquery) • Column list on the left side of operator must be in parentheses • Use the IN operator for WHERE and HAVING clauses Dr. Chen, Oracle Database System (Oracle) 27 Multiple-Column Subquery in a FROM Clause Query10: List all books that have a higher-than-average selling price compared with other books in the same category. SELECT category, AVG(retail) cataverage FROM books GROUP BY category; CATEGORY CATAVERAGE ------------ ---------COMPUTER 52.85 COOKING 24.35 CHILDREN 34.45 LITERATURE 39.95 BUSINESS 31.95 FITNESS 30.95 FAMILY LIFE 55.975 SELF HELP 29.95 it is considered a new table of “a” Figure 12-19 Dr. Chen, Oracle Database System (Oracle) Multiple-column subquery in a FROM clause 28 Multiple-Column Subquery in a FROM Clause (2nd solution) Figure 12-20 Using a Join with a multiple-column subquery in the FROM clause Dr. Chen, Oracle Database System (Oracle) 29 Multiple-Column Subquery in a WHERE Clause Query11(#7): List book titles, retail value and category that match the highest retail value for any book category - revisit (the right solution) Retail might match “MAX” from a different category. Hoewver, this example returns the same answer (by luck) as the right one. Returns multiple columns for evaluation Figure 12-10: Multiple-row subquery with the IN operator Dr. Chen, Oracle Database System (Oracle) Figure 12-21 Multiple-column subquery in a WHERE clause 30 NVL Function (also see p. 359) • The NVL function is to address problems caused when performing arithmetic operations with fields that might contain NULL values. • NULL value is the absence of data, not a blank space or a zero. • NVL(x,y) where y represents the value to substitute if x is NULL. Dr. Chen, Oracle Database System (Oracle) 31 NULL Values Query11: List all customers (customer#) who referred customer 1005 has referred any other customers to JustLee Books. Q: what causes the problem? -- chapter 12, Figure 12-22; p.449 SELECT customer# FROM customers WHERE referred = (SELECT referred FROM customers WHERE customer# = 1005); SELECT referred FROM customers WHERE customer# = 1005; Figure 12-22 Flawed query: NULL results from a subquery Dr. Chen, Oracle Database System (Oracle) REFERRED ---------32 When a subquery might return NULL values, use NVL function SQL> select customer#, referred from customers; CUSTOMER# REFERRED ------------------1001 1002 1003 1004 1005 1006 1007 1003 1008 1009 1003 1010 1011 1012 1013 1006 1014 1015 1016 1010 1017 1018 1019 1003 1020 Figure 12-23 Using the NVL function to handle NULL values Dr. Chen, Oracle Database System (Oracle) 20 rows selected. 33 IV. Uncorrelated Subqueries • Processing sequence – Inner query is executed first – Result is passed to outer query – Outer query is executed • Most of subqueries we studied are uncorrelated subqueries. Dr. Chen, Oracle Database System (Oracle) 34 Nested Subqueries • Maximum of 255 subqueries if nested in the WHERE clause • No limit if nested in the FROM clause • Innermost subquery is resolved first, then the next level, etc. Dr. Chen, Oracle Database System (Oracle) 35 Nested Subqueries (continued) Query12: List the name of the customer who has ordered the most books (4 books in this case) on one order (not including multiple quantities of the same book). • Innermost is resolved first (A), then the second level (B), then the outer query (C) -- chapter 12, Figure 12-27; p.454 SELECT customer#, lastname, firstname FROM customers JOIN orders USING (customer#) WHERE order# IN (SELECT order# FROM orderitems GROUP BY order# HAVING COUNT(*) = (SELECT MAX(COUNT(*)) FROM orderitems GROUP BY order#)); Dr. Chen, Oracle Database System (Oracle) Figure 12-27 Nested subqueries (A): returns 4 (B): returns 1007 1012 36 Subquery in a DML action Figure 12-28 Dr. Chen, Oracle Database System (Oracle) An UPDATE statement using a subquery 37 Exercises • Practice all the examples in the text. • A Script file is available on the Bb (file name: ch12Queries.sql) • After completing all examples, do the HW. In-class Exercise • #3 (p.468) Dr. Chen, Oracle Database System (Oracle) 38 Homework - Hands-On Assignments Email me with one attachment (Oracle_ch12_Spool_Lname_Fname.) to: chen@jepson.gonzaga.edu with subject title of Bmis441-01_Oracle_ch12 (or Bmis441-02_Oracle_ch12) Read and Practice all examples on Chapters 12 • 1. Run the script files (in the folder \oradata\chapter12\): JLDB_Build_12.sql • 2. Read Oracle assignment and create a script file Oracle_ch12_Lname_Fname.sql for questions (#1,2, 5, 10; p. 468) on “Hands-on Assignments”. Use appropriate COLUMN statements to produce readable outputs • 3. Execute and test one problem at a time and make sure they are all running successfully. • 4. When you done, spool the script files (see next slide for spooling instructions) and UPLOAD the file (Oracle_ch12_Spool_Lname_Fname.txt) to the Bb by the midnight before the next class. Dr. Chen, Oracle Database System (Oracle) 39 How to Spool your Script and Output Files After you tested the script file of Oracle_ch12_Lname_Fname.sql successfully, follow the instructions below to spool both script and output files: Step 0. Run the following script file from SQL*Plus (since you have created JLDB tables) – Start c:\oradata\chapter12\JLDB_Build_12.sql • 1. type the following on SQL> – Spool c:\oradata\Oracle_ch12_Spool_Lname_Fname.txt (make sure your name is entered) • 2. open Oracle_ch12_Lname_Fname.sql that you already tested • 3. copy and paste all the SQL commands (including all comments) to the SQL*PLUS • 4. type Spool Off on the SQL> The output should contain your personal information, all SQL commands and their solution on the .txt file and saved in C: drive (oradata\ folder) UPLOAD the spooled file (.txt) to Bb. Dr. Chen, Oracle Database System (Oracle) 40 Summary • A subquery is a complete query nested in the SELECT, FROM, HAVING, or WHERE clause of another query – The subquery must be enclosed in parentheses and have a SELECT and a FROM clause, at a minimum • Subqueries are completed first; the result of the subquery is used as input for the outer query • A single-row subquery can return a maximum of one value • Single-row operators include =, >, <, >=, <=, and <> • Multiple-row subqueries return more than one row of results Dr. Chen, Oracle Database System (Oracle) 41 Summary (continued) • Operators that can be used with multiple-row subqueries include IN, ALL, ANY, and EXISTS • Multiple-column subqueries return more than one column to the outer query • NULL values returned by a multiple-row or multiplecolumn subquery will not present a problem if the IN or =ANY operator is used • Correlated subqueries reference a column contained in the outer query • Subqueries can be nested to a maximum depth of 255 subqueries in the WHERE clause of the parent query Dr. Chen, Oracle Database System (Oracle) 42 Summary (continued) • With nested subqueries, the innermost subquery is executed first, then the next highest level subquery is executed, and so on, until the outermost query is reached • A MERGE statement allows multiple DML actions to be conditionally performed while comparing data of two tables Dr. Chen, Oracle Database System (Oracle) 43