Download presentation
Presentation is loading. Please wait.
Published byClifton Austin Modified over 9 years ago
1
Database Programming Sections 6 –Subqueries, Single Row Subqueries, Multiple-column subqueries, Multiple-row Subqueries, Correlated Subqueries 11/2/10, used 2013
2
Subqueries Subqueries don’t use the following operators: BETWEEN...AND, IN, LIKE, or IS NOT NULL The above operators will execute if and only if they return only one row If more than one value returned, error will occur Null value returned then no rows displayed Lesson Preparation Students have used the comparison operators from the very beginning of this course. Ask them why single-row subqueries can’t use other comparison operator conditions such as BETWEEN...AND, IN, LIKE, or IS NOT NULL? Answer: If any of the subqueries using these operators return only one row, the subquery will execute. If more than one value is returned, an error will occur. If a null value is returned, no rows will be displayed. The type of subquery introduced in lesson 1 is also known as non-correlated subqueries. Correlated subqueries will be the subject of a later lesson (6-5), but the basic difference between them is that a non-correlated subquery does not perform a join between the inner and outer table inside the subquery itself. Marge Hohly
3
SUBQUERY SELECT statement that is embedded in a clause of another SELECT statement Can be placed in the WHERE clause, the HAVING clause, and the FROM clause. The inner query is called the “subquery” Subquery executes first and its output is used to complete the query condition for the main or outer query. SELECT select_list FROM table WHERE expression operator (SELECT select_list FROM table); Chapter 6 11/9/10 The subquery executes once before the main query. The results of the inner query is used in the main or outer query. SELECT last_name, salary FROM employees WHERE salary> (SELECT salary Where last_name = 'Abel'); Subqueries are sometimes known as ‘inner queries.’ When subqueries are used, the main query is sometimes called the ‘outer query.’ Subqueries are SELECT statements that are embedded in the clause of another SELECT statement. They can be placed in the WHERE clause, in the HAVING clause, and the FROM clause also. A subquery always executes first and the output from the subquery is used to complete a query condition for the main or outer query. Marge Hohly
4
Subquery example SELECT last_name FROM employees WHERE salary > (SELECT salary FROM employees WHERE employee_id = 104); Run inner query and get the 6000 for the where clause Marge Hohly
5
SUBQUERIES Guidelines for using subqueries are:
The subquery is enclosed in parentheses. The subquery is placed on the right side of the comparison condition. The outer and inner queries can get data from different tables. Only one ORDER BY clause can be used for a SELECT statement; and, if specified, it must be the last clause in the main(outer) SELECT statement. The only limit on the number of subqueries is the buffer size the query uses. SELECT last_name, salary, department_id FROM employees WHERE department_id = (SELECT department_id FROM departments Where department_name= 'Sales'); Let’s review some guidelines for using subqueries. Subqueries are always enclosed in parentheses. When a comparison condition is used, a subquery is always placed on the right side of this comparison condition. The outer and inner queries do not have to get data from the same table. Only one ORDER BY clause can be used for the SELECT statement and, if specified, it must be the last clause in the main SELECT statement. ORDER BY is never used in a subquery. It would serve no purpose as the results of the subquery are not displayed, but are used by the outer query. And the last guideline, there is no real limit to the number of subqueries to be used in a SELECT statement. It is only limited by the buffer size in the database. Marge Hohly
6
SUBQUERIES There are two types of subqueries:
Single-row subqueries that use single-row operators (>,=,>=,<,<>,<=) and return only one row from the inner query. Multiple-row subqueries that use multiple-row operators (IN, ANY, ALL, or BETWEEN) and return more than one row from the inner query. There are two types of subqueries, single-row subqueries and multiple row subqueries. Single-row subqueries only return one row from the inner query or the subquery. They use operators such as greater than, equal, greater than or equal, less than, not equal to, and less than or equal to. Multiple-row subqueries use multiple row operators such as, IN, ANY, and ALL, or BETWEEN. And, can return more than one row from the inner query. If a single-row subquery brings back more than one row of data, an error will be generated. Marge Hohly
7
Single-Row Subqueries
Return only one row Use single-row comparison operators (=, >,>=, <, <=, <>) Always: Enclose the subquery in parentheses Place the subquery on the right hand side of the comparison condition. Marge Hohly
8
Single-row subqueries
The outer and inner queries can get data from different tables Only one ORDER BY clause can be used for a SELECT statement, and if specified, it must be the last clause in the main SELECT statement The only limit on the number of subqueries is the buffer size that the query uses. Review the subquery rules with students. Point out that (at least for a single-row subquery) an ORDER BY clause in the subquery would not make sense; how can you order a single row? And, why would you sort something you will never see? Marge Hohly
9
SINGLE-ROW SUBQUERY SELECT last_name FROM employees WHERE salary > (SELECT salary FROM employees WHERE last_name = ‘Abel’); Subquery returns 11000, thus the main SELECT statement returns all employees with a salary greater than What if there is more than one Abel in the company?? Discuss example from text Emphasize that the single-row operators can return only one row to the outer query. Note: The sample data shown is not in the database. SELECT id, first_name,last_name, birthdate FROM f_staffs WHERE birthdate >= (SELECT birthdate WHERE last_name = 'Tuttle'); The single-row subquery in this example, looks at the birth date for Tuttle and returns that value to the outer query. Then it’s compared to the birthdate of all employees and only those employees, whose birthday is greater than or matches Tuttle’s, are listed in the query results. This query only works if one employee has a last name of Tuttle. If more than one employee has the last name of Tuttle, the query would fail. When writing subqueries, it is often helpful to write and execute the inner query first, then build the main or outer query around it. Marge Hohly
10
Subquery SELECT last_name FROM employees WHERE department_id = (SELECT department_id FROM employees WHERE last_name = ‘Grant’); Because Grant has a null value for department_id the inner query will return a null value. The outer query will return no rows, because comparing a value with null always yields a null. Remind students that a WHERE condition returns only those rows for which the condition is TRUE. And NULL is not TRUE (it is not FALSE either!). Marge Hohly
11
Subqueries from Different Tables
The outer and inner queries can get data from different tables. Who works in the Marketing department? SELECT last_name, job_id, department_id FROM employees WHERE department_id = (SELECT department_id FROM departments WHERE department_name = ‘Marketing’) ORDER BY job_id; Explain the graphic: the two subqueries retrieve data from two different tables and return it to the outer query. Note: Not all data is displayed in the graphic. Point out that both the subqueries are single-row subqueries. Marge Hohly
12
Subqueries from Different Tables
Group functions can be used in subqueries. A group function without a GROUP BY clause in the subquery returns a single row. Which Global Fast Foods staff earn less than the maximum salary? SELECT last_name, first_name, salary FROM f_staffs WHERE salary < (SELECT MAX(salary) FROM f_staffs); Review the following group functions: MIN, MAX, AVG, COUNT, and SUM. In the example shown, substitute MIN and AVG in the subquery and discuss what result would be returned. MIN: Will someone have a salary less than the minimum salary? AVG: Return the employees whose salary is less than the average salary for all employees. Marge Hohly
13
Error Example SELECT department_id, department_name FROM departments WHERE department_id = (SELECT department_id FROM employees WHERE salary < 4000); What will result? report error: ORA-01427: single-row subquery returns more than one row Marge Hohly
14
SUBQUERIES FROM DIFFERENT TABLES
Subqueries are not limited to just one inner query. As the example illustrates, there can be more than one subquery returning information to the outer query. Also, the outer and inner queries can get data from different tables. SELECT last_name,job_id,salary,department_id FROM employees WHERE job_id= (SELECT job_id FROM employees WHERE employee_id = 141) AND department_id = (SELECT department_id FROM departments WHERE location_id = 1500); Subquery returns job_id = ST_CLERK and department_id = 50 Single-row subqueries: MUST - return only one row - use single-row comparison operators (=, >, >=, <, <=, <>) - enclosed subquery in parentheses - place subquery on the right hand side of the comparison operator SELECT last_name, job_id, department_id FROM employees WHERE department_id = (SELECT department_id FROM departments WHERE department_name = ‘Marketing’) ORDER BY job_id; Marge Hohly
15
Results of previous query
SELECT last_name,job_id,salary,department_id FROM employees WHERE job_id= (SELECT job_id WHERE employee_id = 141) AND department_id = (SELECT department_id FROM departments WHERE department_id= 50); Marge Hohly
16
SUBQUERIES Group functions can be used in single-row subqueries. The inner query returns a single row to the outer query. SELECT last_name,first_name,salary FROM f_staffs WHERE salary < (SELECT MAX(salary) FROM f_staffs); This example shows the use of group functions in single-row subqueries. This is a common use of these subqueries. In this case, the SELECT clause returns last name first name and salary. The WHERE clause tells us to return the rows that contain a salary value that is less than the MAX salary. The inner query returns 60, the maximum salary for any employee in the table. The outer query then returns all those employees whose salary is less than the maximum, or 60. Marge Hohly
17
Example results Subquery returns MAX(salary) = 60
SELECT last_name,first_name,salary FROM f_staffs WHERE salary < (SELECT MAX(salary) FROM f_staffs); Marge Hohly
18
Multiple-Column Subqueries
SELECT employee_id, manager_id, department_id FROM employees WHERE (manager_id,department_id) IN (SELECT manager_id,department_id WHERE employee_id IN (149,176)) AND employee_id NOT IN (149,176); Subqueries can use one or more columns. If they use more than one column, they are called multiple-column subqueries. A multiple-column subquery can be either pair-wise comparisons or non-pair-wise comparisons. This slide introduces the concept of multiple-column subqueries and them being pair-wise and non-pair-wise. Example above is a “pair-wise” subquery. The example on the slide is that of a pair-wise multiple-column subquery because the subquery returns more than one column. It compares the values in the MANAGER_ID column and the DEPARTMENT_ID column of each row in the EMPLOYEES table with the values in the MANAGER_ID column and the DEPARTMENT_ID column for the employees with the EMPLOYEE_ID 149 or 174. First, the subquery to retrieve the MANAGER_ID and DEPARTMENT_ID values for the employees with the EMPLOYEE_ID 149 or 174 is executed. These values are compared with the MANAGER_ID column and the DEPARTMENT_ID column of each row in the EMPLOYEES table. If the values match, the row is displayed. In the output, the records of the employees with the EMPLOYEE_ID 149 or 174 will not be displayed. Make sure you demonstrate this example, and also the one on the following slide to the students can clearly see the difference in the result set. Subqueries that refer to more than one column are called multiple-column subqueries. They can be written in two different ways. A single subquery that has more than one column in its SELECT clause is called a ‘pair-wise’ subquery. A non-pair-wise, multi-column subquery is written as two separate subqueries connected by the operator AND, or the operator OR. In this example, managers and departments are matched up to return a set of results. Marge Hohly
19
Multiple-Column subqueries
Multiple-column can be written two ways Single subquery that has more than one column in the Select clause is called a “pair-wise” subquery A “non-pair-wise”, multi-column subquery is written as two separate subqueries connected by either an AND or OR operator Marge Hohly
20
Multiple-Column Subqueries
Non-pair-wise multiple-column subquery uses more than one column It compares them one at a time Comparisons take place in different subqueries Write one subquery per column Marge Hohly
21
Multiple-Column Subqueries
SELECT employee_id, manager_id, department_id FROM employees WHERE manager_id IN (SELECT manager_id WHERE employee_id IN (176,149)) AND department_id IN (SELECT department_id AND employee_id NOT IN(174,199); This slide example shows a non-pair-wise comparison of the columns. It displays the EMPLOYEE_ID, MANAGER_ID, and DEPARTMENT_ID of any employee whose manager ID matches any of the manager IDs of employees whose employee IDs are either 174 or 199 and DEPARTMENT_ID match any of the department IDs of employees whose employee IDs are either 174 or 199. First, the subquery to retrieve the MANAGER_ID values for the employees with the EMPLOYEE_ID 174 or 199 is executed. Similarly, the second subquery to retrieve the DEPARTMENT_ID values for the employees with the EMPLOYEE_ID 174 or 199 is executed. The retrieved values of the MANAGER_ID and DEPARTMENT_ID columns are compared with the MANAGER_ID and DEPARTMENT_ID column for each row in the EMPLOYEES table. If the MANAGER_ID column of the row in the EMPLOYEES table matches with any of the values of the MANAGER_ID retrieved by the inner subquery and if the DEPARTMENT_ID column of the row in the EMPLOYEES table matches with any of the values of the DEPARTMENT_ID retrieved by the second subquery, the record is displayed. Demonstrate this example as a follow up to the previous slide, and compare the result sets from the two queries. Here is an example of using more than one subquery in a SELECT statement. In this case, both of the subqueries are in the WHERE clause; they are connected by an AND operator. The first inner query brings back the manager_id of all employees who have an employee_id that is the same as 174 or 199. The second subquery brings back the department ids of all employees who have an employee_id that is the same as 174 or 199. The AND connects the subqueries and WHERE clause in such a way that employees 174 and 199 are returned. Then the outer SELECT statement will list those employees. Take time to write this query and examine the output. Make sure the output matches your expectations. Marge Hohly
22
Example Write a query to find the name of the Global Fast Foods employee who makes the most money? Solution next slide Marge Hohly
23
Solution using subquery
Marge Hohly
24
EXIST & NOT EXIST in Subqueries
EXIST and its opposite NOT EXIST are another two clauses that can be used when testing for matches in subqueries. EXISTS test for a TRUE, or a matching result in the subquery. If you wanted to see how many employees were only employees and not also a manager, you could use NOT EXIST: SELECT count(*) FROM employees t1 WHERE NOT EXISTS (SELECT NULL FROM employees t2 WHERE t2.manager_id = t1.employee_id ); In this example the subquery is selecting a NULL value to emphasize the fact that we are testing for an occurrence of rows in the subquery, we are not wanting to return anything but TRUE or FALSE from it. In this example, we are asked to evaluate all employees and only return a count of those employees who are individual contributors or employees without direct reports. The syntax of the inner query returns null because we only want to test the existence (TRUE or FALSE) of employee records for those employees who have direct reports. We really do not want any data from the inner query. The use of the clause NOT EXIST would be true in the instance I would encounter an employee record who's employee id isn't also a manager_id. Marge Hohly
25
EXIST & NOT EXIST in Subqueries
SELECT count(*) FROM employees t1 WHERE t1.employee_id NOT IN (SELECT t2.manager_id FROM employees t2 ); Same as previous query with NOT IN rather than NOT EXIST Different results – Why? Beware of NULLS in subqueries – NOT EXISTS safer Ask class what is causing this result? The cause of the strange result is due to the NULL value returned by the subquery. One of the rows in the employees table does not have a manager, and this makes the entire result wrong. Subqueries can return three values: TRUE, FALSE and UNKNOWN. A NULL in the subquery result set will return a UNKNOWN, which Oracle cannot evaluate, so it doesn’t. BEWARE of NULLS in subqueries when using NOT IN. If you do not know if the subquery will return null values, always use NOT EXISTS. It is safer. NOT IN and NOT EXISTS are NOT the same. Three major differences: the number of records read, execution speed and the evaluation of NULL. If there is a possibility of null values being returned from subqueries when using NOT IN, always use NOT EXISTS instead. Marge Hohly
26
EXIST & NOT EXIST in Subqueries
FOR x IN ( SELECT * FROM employees t1 ) LOOP IF ( EXISTS ( SELECT NULL FROM employees t2 WHERE t1.employee_id = t2.manager_id ) THEN OUTPUT THE RECORD END IF END LOOP EXISTS executed a Full Table Scan of outer table then loops through the subquery results The way EXISTS and NOT EXISTS are executed by Oracle is very different from the way IN and NOT IN are executed. When the database is executing an IN with a Subquery, it evaluates the Subquery, typically Distincts that query and then joins the result to the outer query to get the result. When an EXISTS is executed it will perform a Full Table Scan of the outer table, and then Oracle will loop through the Subquery result rows one by one to see if the condition is true. It will execute like this: See the example above which is a loop. Marge Hohly
27
EXIST & NOT EXIST in Subqueries
One final note about EXISTS and IN. IN will generally execute faster, as it can use any existing indexes on the outer table, which EXISTS cannot, but it does depend on the size of the tables; which one of the expressions will run faster. A small outer table joined to a very big inner table can still execute very fast using EXISTS, perhaps even faster that the same statement using IN. And remember: be careful when handling NULLs. Marge Hohly
28
Single-row subqueries review
They: Return only one row Use single-row comparison operators (=, >, >=, <. <=, <>) Always: Enclose the subquery in parentheses Place the subquery on the right hand side of the comparison condition. Marge Hohly
29
Single-row vs. Multiple-row
SELECT first_name, last_name FROM employees WHERE salary = (SELECT salary WHERE department_id = 20); See next slide Point out that for the same reason, we cannot use <, > or <> in the WHERE clause condition. The key point is that it doesn’t make sense to compare one value with several values. Is less than (13000,6000)? The inner query returns multiple values therefore the outer query will return an error. You should consider using a multiple row query which would not return an error. Marge Hohly
30
Single-row vs. Multiple-row
Whose salary is equal to the salary of an employee in department 20 ? Why does this example not work? Because there is more than one employee in department 20, so the subquery returns multiple rows. We call this a multiple-row subquery. The problem is the equals sign (=) in the WHERE condition. How can one value be equal to (or not equal to) more than one value? It’s a silly question, isn’t it? Error Code: ORA-01427: single-row subquery returns more than one row Marge Hohly
31
GROUP Functions in HAVING Clause
Subqueries can also be placed in the HAVING clause. Remember that the HAVING clause is similar to the WHERE clause, except that the HAVING clause is used to restrict groups and always has a group condition (such as MIN, MAX, AVG) stated. Because the HAVING clause always has a group condition, the subquery will nearly always have a group condition as well. Marge Hohly
32
GROUP Functions in HAVING Clause
HAVING clause is used to restrict groups and always has a group condition (such as MIN, MAX, AVG) stated See next page for example Marge Hohly
33
GROUP Functions in HAVING Clause
SELECT department_id, MIN(salary) FROM employees GROUP BY department_id HAVING MIN(salary) > (SELECT MIN(salary) FROM employees WHERE department_id = 50); Inner query returns 7500 for minimum salary Which departments have a lowest salary that is greater than the lowest salary in department 50? In this example, the subquery selects and returns the lowest salary in department 50. The outer query uses this value to select the department ID and lowest salaries of all the departments whose lowest salary is greater than that number. The HAVING clause eliminated those departments whose MIN salary was less than department 50’s MIN salary. Work through this example with students, explaining the sequence of execution steps: The subquery executes and returns the lowest salary in department 50: 2500. The outer query groups the employee rows by department and calculates the lowest salary in each department. The HAVING clause selects only those groups of departments whose lowest salary is greater than 2500. This example demonstrates group functions in the HAVING clause of a SELECT statement. Remember, HAVING clauses are used along with GROUP BY clauses. Let’s look at the inner query first. SELECT MIN salary FROM employees WHERE department id equals 50. The lowest salary for any employee in department id 50 is Since the GROUP BY clause separates the data into different departments, these departments are then compared to the minimum salary. If the minimum salary in each department is greater than the minimum salary of department 50, which is 2500, these departments will display as the query results. So, in the results, the minimum salaries for the departments listed are greater than the minimum salary of department 50. Marge Hohly
34
Multi-row subquery Sect. 6 Lesson 3
1. Ask yourself what part of the query defines the “where” criteria. 2. Ask yourself if you know all the components of the “where” criteria; if not, you could be looking at a subquery in the WHERE clause. a. When writing the subquery, consider whether you will need a single row or multiple rows as the result. b. Next, consider what the criteria is for selection -- WHERE clause for subquery. c. Enclose the subquery within parentheses, and then complete the outer query criteria -- WHERE clause -- by selecting the comparison operator: i. If a single-row subquery, then pick =, <>, >, or < as the operator. ii. If a multirow subquery, then pick IN, ALL, or ANY. d. Make sure you are comparing “apples to apples” and “oranges to oranges” -- i.e., make sure the column(s) selected in the subquery match the columns being tested by the WHERE clause in the outer query. e. Apply any additional criteria needed to the outer query, using ANDs, ORs, and NOTs. Marge Hohly
35
Multiple-Row Subqueries
Subqueries that return more than one value are called multiple-row subqueries When used in a WHERE clause, the multiple-row subquery must use a multiple-row operator, such as IN, ANY, or ALL. The multiple-row operators are: IN ANY ALL The NOT operator can be used with any of these three operators See example on next slide So far, we’ve examined single-row subqueries, which may return only one value. Multiple-row subqueries may return more than one value. The multiple row operators are: IN, ANY, and ALL. You can add NOT to any one of these operators to reverse its meaning such as, NOT IN, NOT ANY, or NOT ALL. Example: SELECT title, year FROM d_cds WHERE year IN (SELECT year FROM d_cds); Marge Hohly
36
Multiple-Row Subqueries cont’d
SELECT employee_id, last_name, salary, department_id FROM employees WHERE salary NOT IN (SELECT salary FROM employees WHERE last_name = ‘King’); SECTION title, year FROM d_cds WHERE year IN (SELECT year WHERE cd_number<93); In this example of a multiple row subquery using IN , the subquery selects the years from each CD less than CD number 93. The IN operator allows this multiple set of values to be passed to the main query. The results of this multi-row subquery include three values, then the outer query matches every CD against one of those three values. If a match is found, the CD information is than displayed. Marge Hohly
37
IN SELECT last_name,salary, department_id FROM employees Where salary IN(SELECT MIN(salary) FROM employees GROUP BY department_id); Print out values for min salary inner query. Marge Hohly
38
ANY The ANY operator compares a value to each value returned by a subquery. SELECT employee_id, last_name, job_id, salary FROM employees WHERE salary < ANY (SELECT salary FROM employees WHERE job_id = ‘IT_PROG’); Results next slide SELECT title, producer FROM d_cds WHERE year < ANY (SELECT year WHERE producer = 'The Music Man'); This example introduces the ANY operator. The query displays the CDs that have a year value less than ANY of the years of those CDs whose producer is ‘The Music Man’. The CDs that result from the query will be less than the maximum year of the subquery, in this case, 2001. Marge Hohly
39
Results of ANY Marge Hohly
40
All Used when the outer-query WHERE clause is designed to restrict rows based on all values returned from the inner query. the inner query will return a list of values. The ALL operator compares a value to every value returned by the inner query. Explain the graphic. Ask students to state what =ALL , < ALL and <> ALL would return in the example shown in the graphic. Run query where producer = ‘The Music Man’ in command file Slide 41 =ALL The outer query would only return those titles that had years = ALL. In this case, no data is found. There is no entry with "The Music Man" producer, one year 2000 and the other 2001. <ALL The outer query would only return those titles that had years less than all the years from "The Music Man" producer. <>ALL The outer query would only return those titles that did not have any of the years returned by the subquery from "The Music Man" producer. SELECT title, producer, year FROM d_cds WHERE year > ALL (SELECT year WHERE producer = 'The Music Man'); The ALL operator compares a value to every value returned in a subquery. The example shown will return any CD title whose year is greater than all the CD title years produced by ‘The Music Man’. The CDs that result from the query will be greater than the maximum year of the subquery, which is 2001. Marge Hohly
41
NULL Values in Subqueries
MANAGER_ID - 100 102 103 124 149 SELECT emp.last_name FROM employees emp WHERE emp.employee_id NOT IN (SELECT mgr.manager_id FROM employees mgr); SQL Query Results No Data One of the values returned by the inner query is a null value, and hence the entire query returns no rows. King does not have a manager. ALSO SEE next slide for corrections that gets correct results. SELECT last_name, employee_id FROM employees WHERE employee_id IN (SELECT manager_id FROM employees); Remember, if a null value is returned from a subquery, then the outer query returns no data. For a single-row subquery this is obvious, but for a multiple-row subquery it is not so obvious. In the case of this example, since one of the employees does not have a manager id, the inner query contains a null value. The outer query will return rows that match the non-null values. However, if ALL is used, the outer query cannot execute against a null value and the query brings back a “No data found” result. Take time to try these variations in Application Express and be able to explain the results that display. Marge Hohly
42
NULL values in subqueries
SELECT emp.last_name FROM employees emp WHERE emp.employee_id NOT IN (SELECT mgr.manager_id FROM employees mgr WHERE mgr.manager_id IS NOT NULL); Now none of the values returned by the inner query is a null value, thus it works. Marge Hohly
43
NULL Example SELECT department_id, department_name FROM departments WHERE department_id = (SELECT department_id FROM employees WHERE salary >60000); SQL Query Results. No data found. No employee has a salary >60000 There is no such thing as = NULL as NULL is not zero! As long as one value in the inner query is NULL the outer query will return no data with ALL operators. It will return values if the operator is either IN or ANY and one value of the inner query is a NULL. Marge Hohly
44
Null Values in Subqueries, cont’d
SELECT emp.last_name FROM employees emp WHERE emp.employee_id NOT IN (SELECT mgr.manager_id FROM employees mgr WHERE mgr.manager_id IS NOT NULL); View results of inner query on next slide. Now, none of the values returned by the inner query is a null value, thus it works. Marge Hohly
45
Results of Inner Query Marge Hohly
46
Examples 1. Select all the employees (name, job ID, salary) in departments 10 and 30. Write two different queries that will produce the desired result. 2. Select the name of all the departments (department name and location id) and order by department number. Do not display the department number in the output. 1. a. SELECT last_name,job_id, salary FROM employees WHERE department_id in (10,30); b. SELECT last_name,job_id, salary FROM employees WHERE department_id = 10 or department_id=30; This is not the most efficient answer, but it does return the correct results: c. SELECT last_name,job_id,salary FROM employees WHERE department_id IN( SELECT department_id FROM departments WHERE department_id IN (10,30)); SELECT department_name, location_id FROM departments ORDER BY department_id; Marge Hohly
47
Possible Answers to examples
SELECT last_name,job_id, salary FROM employees WHERE department_id in (10,30); SELECT last_name,job_id, salary FROM employees WHERE department_id = 10 or department_id=30; This is not the most efficient answer, but it does return the correct results: SELECT last_name,job_id,salary FROM employees WHERE department_id IN( SELECT department_id FROM departments WHERE department_id IN (10,30)); SELECT department_name, location_id FROM departments ORDER BY department_id; Marge Hohly
48
Group By and Having in multi-row subqueries
If you want to find the departments whose minimum salary is less than the salary of any employee who works in departments 10 or 20? SELECT department_id,MIN(salary) FROM employees GROUP BY department_id HAVING MIN(salary) <ANY (SELECT salary FROM employees WHERE department_id IN (10,20)); Both group by and having can be used in multiple row queries. Marge Hohly
49
GROUP BY and HAVING You can have a GROUP BY in the subquery Which departments have a minimum salaries which is greater than the minimum, salaries in departments less than 50? SELECT department_id, MIN(salary) FROM employees GROUP BY department_id HAVING MIN(salary)>ALL (SELECT MIN(salary) FROM employees WHERE department_id < GROUP BY department_id); Marge Hohly
50
Single-row vs. multi-row subqueries
If you believe there is a possibility that the inner query could return more than one value write a multi-row subquery. When in doubt use a multi-row subquery. It is better to be safe than sorry. Marge Hohly
51
Single-row vs. multi-row subqueries
ONE LAST POINT ABOUT SUBQUERIES It would be better to write a multiple-row subquery. The multiple-row subquery syntax will still work even if the subquery returns a single row. If in doubt, write a multiple-row subquery ! Point out that when we use IN, ANY or ALL to compare with a list of values, they will still work even if there is only one value in the list. Does IT_PROG equal IT_PROG? Yes. Is IT_PROG in a list of values which contains the single value IT_PROG? Also yes. Marge Hohly
52
Correlated Subqueries
What to Watch For Students will be wondering what the basic difference is between the subqueries from the last two lessons and these. The best example is probably the case of having to list employees who makes more that the average for their department. So we have to calculate the AVG(salary) for departments in the inner query, but then compare that result to the department_id of each and every one of the employees returned by the outer query. Marge Hohly
53
Correlated Subqueries
Whose salary is higher than the average salary of their department? To answer that question we need to write a correlated subquery. Correlated subqueries are used for row-by-row processing. Each subquery is executed once for every row of the outer query. With a normal subquery, the inner SELECT query runs first and executes once, returning values to be used by the main query. A correlated subquery, however, executes once for each candidate row considered by the outer query. In other words, the inner query is driven by the outer query. The part that makes this example a correlated subquery is marked in red. Make sure you point out that correlated subqueries executes completely differently to non-correlated subqueries, in as much as they are driven by the outer query. So the outer query is executed, the first row returned and for THAT row the inner query is executed. So if the outer query returns 10,000 rows, the inner query will be executed 10,000 times in total. See next slide Marge Hohly
54
Correlated Subquery SELECT o.first_name, o.last_name, o.salary FROM employees o WHERE o.salary > (SELECT AVG(i.salary) FROM employees i WHERE i.department_id = o.department_id); The slide shows an example of the query outlined for slide 1. Make sure the query is demonstrated both as a correlated and non-correlated subquery. To make the example non-correlated, simply remove the WHERE clause from the inner query. Correlated subqueries are used whenever the rows returned from a subquery need to be examined one at a time. Usually, the entire result set from a subquery is returned to the outer query for processing. In contrast, a correlated subquery is processed once for each row in the outer query. If a subquery references a column from a table that is also present in the outer query then it is correlated. The purpose of the statement in this example is to list those employees that earn more than the average salary for their department. Since the average salary for these departments are not stored in the database, these values need to be calculated at run time by the subquery. The table alias “o” stands for ‘outer,’ “i” stands for ‘inner.’ The salary of each employee selected by the outer query must be compared to the average salary in the department where the employee is assigned. The WHERE clause in this subquery joins the two tables together, matching the employee’s department, sending back the average salary for that department. The outer WHERE clause takes over then, comparing the employee’s salary to the average for his or her department. Marge Hohly
55
WITH clause If you have to write a very complex query with joins and aggregations used many times, you can write the different parts of the statement as query blocks and then use those same query block in a SELECT statement. Oracle allows you to write named subqueries in one single statement, as long as you start your statement with the keyword WITH. The WITH clause retrieves the results of one or more query blocks and stores those results for the user who runs the query. The WITH clause improves performance. The WITH clause makes the query easier to read. This slide introduces the WITH clause, which is a very different and what seems like a much more complex query structure. It is not really. But DO try to keep it simple. The keyword WITH is used to name subqueries so that they can be used multiple times within a complex SELECT statement. Oracle runs the WITH clause first, executing the SQL statements and storing the results in memory. The main query runs next, accessing the stored data as necessary. Marge Hohly
56
WITH clause The syntax for the WITH clause is as follows:
WITH subquery-name AS (subquery), subquery-name AS (subquery) SELECT column-list FROM {table | subquery-name | view} WHERE condition is true; Syntax for the WITH clause Marge Hohly
57
WITH clause Write the query for the following requirement:
Display the department name and total salaries for those departments whose total salary is greater than the average salary across departments. To solve this query you will need to first get the total salaries per department, then the average salary per department and then you can list just the ones with total salary greater than the average of all departments. See example a few slides ahead. Marge Hohly
58
WITH clause Let’s examine an example of a WITH clause.
Let’s start by creating two subqueries, one called dept_costs and a second called avg_cost. Avg_cost uses the result of dept_cost and once these two subqueries have been run the actual query itself is executed. The query itself selects from both dept_cost and avg_cost. By creating the subqueries first, you do not need to create two temporary tables to hold the results of the SUM of salary per department and the AVG of department salaries. See example on next slide Marge Hohly
59
WITH clause WITH dept_costs AS ( SELECT d.department_name, SUM(e.salary) AS dept_total FROM employees e JOIN departments d ON e.department_id = d.department_id GROUP BY d.department_name), avg_cost AS ( SELECT SUM(dept_total)/COUNT(*) AS dept_avg FROM dept_costs) SELECT * FROM dept_costs WHERE dept_total > (SELECT dept_avg FROM avg_cost) ORDER BY department_name; Make sure this example is demonstrated, and build it up slowly, so run one query at a time, see the results and make sure to demonstrate to the students HOW the data from one subquery feeds into subsequent queries. Ask your students how the same result could be achieved, if you were not using a WITH clause. The answers will vary, but may include the creation of tables to hold the interim results. Note: The red (avg_cost) and green (dept_cost) are like temporary tables which exist in memory to be used in this query. The blue dept_total and the purple dept_avg are being calculated from the temporary tables to be compared in this query. This keeps you from having to actually create tables that you would not use for any other purpose than this query. Marge Hohly
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.