11 Chapter 4: Subqueries 4.1: Noncorrelated Subqueries 4.2: Correlated Subqueries (Self-Study)

Slides:



Advertisements
Similar presentations
WHERE Clause Chapter 2. Objectives Limit rows by using a WHERE clause Use the LIKE operator Effect of NULL values Use compound conditions Use the BETWEEN.
Advertisements

© 2007 by Prentice Hall (Hoffer, Prescott & McFadden) 1 Joins and Sub-queries in SQL.
DatabaseDatabase cs453 Lab8 1 Ins.Ebtesam AL-Etowi.
Introduction to SQL Session 2 Retrieving Data From Multiple Tables.
11 Chapter 3: Displaying Query Results 3.1 Presenting Data 3.2 Summarizing Data.
Objectives After completing this lesson, you should be able to do the following: Define subqueries Describe the types of problems that the subqueries.
Enhancements to the GROUP BY Clause Fresher Learning Program January, 2012.
Using Relational Databases and SQL Department of Computer Science California State University, Los Angeles Lecture 8: Subqueries.
1 Chapter 4: Creating Simple Queries 4.1 Introduction to Querying Data 4.2 Filtering and Sorting Data 4.3 Creating New Columns with an Expression 4.4 Grouping.
11 Chapter 2: Basic Queries 2.1: Overview of the SQL Procedure 2.2: Specifying Columns 2.3: Specifying Rows.
1 Chapter 4: Introduction to Lookup Techniques 4.1 Introduction to Lookup Techniques 4.2 In-Memory Lookup Techniques 4.3 Disk Storage Techniques.
Database Programming Sections 6 –Subqueries, Single Row Subqueries, Multiple-column subqueries, Multiple-row Subqueries, Correlated Subqueries 11/2/10,
11 Chapter 7: Creating Tables and Views 7.1 Creating Views with the SQL Procedure 7.2 Creating Tables with the SQL Procedure (Self-Study) 7.3 Integrity.
SQL Chapter Two. Overview Basic Structure Verifying Statements Specifying Columns Specifying Rows.
1 Multiple Table Queries. 2 Objectives  Retrieve data from more than one table by joining tables  Using IN and EXISTS to query multiple tables  Nested.
Database Systems Design, Implementation, and Management Coronel | Morris 11e ©2015 Cengage Learning. All Rights Reserved. May not be scanned, copied or.
Copyright © 2004, Oracle. All rights reserved. Lecture 4: 1-Retrieving Data Using the SQL SELECT Statement 2-Restricting and Sorting Data Lecture 4: 1-Retrieving.
1 Chapter 6: Using Prompts in Tasks and Queries 6.1 Prompting in Projects 6.2 Creating and Using Prompts in Tasks 6.3 Creating and Using Prompts in Queries.
Oracle 11g DATABASE DEVELOPMENT LAB2. Chapter- 2  These commands, which could be issued from SQL*Plus or SQL Developer,  will make it possible to log.
INSERT Statement. 2 home back first prev next last What Will I Learn? Give examples of why it is important to be able to alter the data in a database.
Performing Advanced Queries Using PROC SQL Chapter 2 1.
Controlling Input and Output
SAS for Data Management and Analysis
IST 210 More SQL Todd Bacastow IST 210: Organization of Data.
# 1# 1 QueriesQueries How do we ask questions of the data? What is SELECT? What is FROM? What is WHERE? What is a calculated field? Spring 2010 CS105.
In this session, you will learn to: Query data by using joins Query data by using subqueries Objectives.
Database Programming Sections 6 –Subqueries, Single Row Subqueries, Multiple-row Subqueries, Correlated Subqueries.
1 Chapter 3 Single Table Queries. 2 Simple Queries Query - a question represented in a way that the DBMS can understand Basic format SELECT-FROM Optional.
CSC314 DAY 9 Intermediate SQL 1. Chapter 6 © 2013 Pearson Education, Inc. Publishing as Prentice Hall USING AND DEFINING VIEWS  Views provide users controlled.
Using Subqueries to Solve Queries
Chapter 6: Set Operators
Writing Basic SQL SELECT Statements
Displaying Query Results
Basic select statement
Subqueries Schedule: Timing Topic 25 minutes Lecture
Chapter 4: Using Lookup Tables to Match Data: Arrays
Using the Set Operators
Basic Queries Specifying Columns
PROC SQL, Overview.
Chapter 5: Using DATA Step Arrays
Using Subqueries to Solve Queries
Writing Correlated Subqueries
Using the Set Operators
More SQL Nested and Union queries, and more
Conditional Processing
Noncorrelated subquery
Correlated Subqueries
A more complex example.
Displaying Queries 2 Display a query’s results in a specified order.
Subsetting Rows with the WHERE clause
Inner Joins.
Using Subqueries to Solve Queries
5 The EXCEPT Operator Unique rows from the first result set that are not found in the second result set are selected.
Reporting Aggregated Data Using the Group Functions
The INTERSECT Operator
Subqueries Schedule: Timing Topic 25 minutes Lecture
3 Views.
A new keyword -- calculated
Using Subqueries to Solve Queries
Subqueries.
Reporting Aggregated Data Using the Group Functions
Using Subqueries to Solve Queries
UNION Operator keywords Displays all rows from both the tables
Using the Set Operators
Reporting Aggregated Data Using the Group Functions
2 Types of Subqueries.
Subqueries Schedule: Timing Topic 25 minutes Lecture
Subqueries Schedule: Timing Topic 25 minutes Lecture
分组函数 Schedule: Timing Topic 35 minutes Lecture 40 minutes Practice
Aggregating Data Using Group Functions
Presentation transcript:

11 Chapter 4: Subqueries 4.1: Noncorrelated Subqueries 4.2: Correlated Subqueries (Self-Study)

22 Chapter 4: Subqueries 4.1: Noncorrelated Subqueries 4.2: Correlated Subqueries (Self-Study)

3 Objectives Define PROC SQL subqueries. Differentiate between correlated and noncorrelated subqueries. Subset data based on values returned a subquery. 3

4 Queries versus Subqueries A query corresponds to a single SELECT statement within a PROC SQL step. 4 proc sql; quit; select * from orion.Staff; select avg(Salary) as MeanSalary from orion.Staff; select Job_Title, avg(Salary) as MeanSalary from orion.Staff group by Job_Title having avg(Salary) > ;

5 Queries versus Subqueries A subquery is a query (SELECT statement) that resides within an outer query (the main SELECT statement). The subquery must be resolved before the main query can be resolved. 5 proc sql; quit; select Job_Title, avg(Salary) as MeanSalary from orion.Staff group by Job_Title having avg(Salary) > (select from ); Subquery Main Query

6 Subqueries return values to be used in the outer query’s WHERE or HAVING clause can return single or multiple values must return only a single column. 6

7 Subqueries There are two types of subqueries: In a noncorrelated subquery, values are passed from the inner query to the outer query. 7 proc sql; quit; select Job_Title, avg(Salary) as MeanSalary from orion.Staff group by Job_Title having avg(Salary) > (select avg(Salary) as MeanSalary from orion.Staff); Stand-alone query continued...

8 Subqueries In a correlated subquery, the outer query must provide information to the subquery before it can be successfully resolved. 8 proc sql; quit; select Employee_ID, avg(Salary) as MeanSalary from orion.Employee_Addresses where 'AU'= (select Country from Work.Supervisors where Employee_Addresses.Employee_ID= Supervisors.Employee_ID);

9 Business Scenario Create a report that displays Job_Title for job groups with an average salary greater than the average salary of the company as a whole. 9

10 Using a Noncorrelated Subquery This demonstration illustrates how to write a noncorrelated subquery. 10 s104d01

11 Noncorrelated Subqueries 11 proc sql; select Job_Title, avg(Salary) as MeanSalary from orion.Staff group by Job_Title having avg(Salary) > (select avg(Salary) from orion.Staff) ; quit; s104d01 Evaluate the subquery first.

12 Noncorrelated Subqueries 12 s104d01 proc sql; select Job_Title, avg(Salary) as MeanSalary from orion.Staff group by Job_Title having avg(Salary) > ( ) ; quit; Then pass the results to the outer query.

13 Noncorrelated Subqueries 13 Partial PROC SQL Output Employee Job Title MeanSalary ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ Account Manager Administration Manager Applications Developer I Applications Developer II Applications Developer IV Auditing Manager Auditor I Auditor II Auditor III BI Administrator IV BI Architect II BI Specialist II 44425

14

Poll Can a subquery contain a subquery?  Yes  No 15

Poll – Correct Answer Can a subquery contain a subquery?  Yes  No 16

17 Business Scenario 17 Each month, the CEO sends a birthday card to each employee having a birthday in that month. Create a report listing the names and addresses of employees with February birthdays.

18 Noncorrelated Subqueries 18 s104d02 proc sql; select Employee_ID, Employee_Name, City, Country from orion.Employee_Addresses where Employee_ID in (select Employee_ID from orion.Employee_Payroll where month(Birth_Date)=2) order by 1; quit; The orion.Employee_Addresses table contains names and addresses. Birth dates are found in the orion.Employee_Payroll table.

19 Noncorrelated Subqueries: How Do They Work? 19 Partial proc sql; select Employee_ID, Employee_Name, City, Country from orion.Employee_Addresses where Employee_ID in (select Employee_ID from orion.Employee_Payroll where month(Birth_Date)=2) order by 1; quit;... s104d02 orion.Employee_Payroll Employee _ID Birth _Date …… DEC JAN FEB DEC NOV JUL FEB MAY1948 …… Step 1: Evaluate the inner query and build a virtual table that satisfies the WHERE criteria.

20 Noncorrelated Subqueries: How Do They Work? 20 proc sql; select Employee_ID, Employee_Name, City, Country from orion.Employee_Addresses where Employee_ID in (120108,120112,120114,120157, , ,…) order by 1; quit;... s104d02 orion.Employee_Payroll Employee _ID Birth _Date …… DEC JAN FEB DEC NOV JUL FEB MAY1948 …… Values returned by the inner query Partial

21 Noncorrelated Subqueries: How Do They Work? 21 proc sql; select Employee_ID, Employee_Name, City, Country from orion.Employee_Addresses where Employee_ID in (120108,120112,120114,120157, , ,…) order by 1; quit; s104d02 orion.Employee_Payroll Employee _ID Birth _Date …… DEC JAN FEB DEC NOV JUL FEB MAY1948 …… Step 2: Pass the values to the outer query for use in the WHERE clause. Partial

22 Noncorrelated Subqueries: Output 22 The SAS System Employee_ID Employee_Name City Country ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ Gromek, Gladys MelbourneAU Glattback, Ellis MelbourneAU Buddery, Jeannette SydneyAU Karavdic, Leonid SydneyAU Phoumirath, Lynelle SydneyAU Kingston, Alban SydneyAU Do these look familiar? They are the employee IDs returned by the inner query.

23

24 Setup for the Poll Open the program s104a01. Change the IN operator to an equal sign (=) in the code as shown on the previous slide. Run the changed program and review the SAS log for messages. What happens when you change the comparison operator to an equal sign? 24 proc sql; select Employee_Name, City, Country from orion.Employee_Addresses where Employee_ID in (select Employee_ID from orion.Employee_Payroll where month(Birth_Date)=2) order by 1; quit;

Multiple Choice Poll What happens when you change the comparison operator to an equal sign? a.Nothing special; the program runs fine. b.You get multiple rows returned in your output. c.You get an error message. d.a and b. 25

Multiple Choice Poll – Correct Answer What happens when you change the comparison operator to an equal sign? a.Nothing special; the program runs fine. b.You get multiple rows returned in your output. c.You get an error message. d.a and b. 26

27 Subqueries That Return Multiple Values When a subquery returns multiple values and the EQUAL operator is used, an ERROR message is generated. The EQUAL operator does not accept any expression that resolves to more than a single value. Example: 27 ERROR: Subquery evaluated to more than one row.  If the subquery returns multiple values, you must use the IN operator or a comparison operator with the ANY or ALL keywords. where Employee_ID=120108, ,

28 The ANY Keyword (Self-Study) If you specify the ANY keyword before a subquery, the comparison is true if it is true for any of the values that the subquery returns. 28 Keyword ANYSignifies… = ANY(20,30,40)=20 or =30 or =40 > ANY(20,30,40)> 20 < ANY(20,30,40)< 40  The values 20,30,40 represent values returned from a subquery.

29 The ANY Keyword (Self-Study) Example:Do any Level IV sales representatives have a salary that is lower than any of the lower-level sales representatives? 29 proc sql; select Employee_ID, Salary from orion.Staff where Job_Title='Sales Rep. IV' and salary < any (select Salary from orion.Staff where Job_Title in ('Sales Rep. I','Sales Rep. II', 'Sales Rep. III')); quit; s104d03 Think < select max ( salary ).

30 The ANY Keyword (Self-Study) Partial PROC SQL Output 30 Level IV Sales Reps Who Earn Less Than Any Lower Level Sales Rep Employee Annual Employee ID Salary ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ $32, $30, $32, $30, $30, $31, $31,750

31 The ALL Keyword (Self-Study) The ALL keyword is true only if the comparison is true for all returned values. 31 Keyword ALLSignifies > ALL(20,30,40)> 40 < ALL(20,30,40)< 20  The values 20,30,40 represent values returned from a subquery.

32 The ALL Keyword (Self-Study) Example:What are the job titles and salaries of the employees who earn more than all Level IV employees? 32 proc sql; select Job_Title, Salary from orion.Staff where Salary > all (select Salary from orion.Staff where Job_Title contains 'IV'); quit; Think > select max ( salary ). s104d04

33 Selecting Data (Self-Study) Partial PROC SQL Output 33 Job Titles and Salaries of Employees That Earn More Than All level IV Employees Employee Annual Employee Job Title Salary ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ Director $163,040 Sales Manager $108,255 Sales Manager $87,975 Chief Executive Officer $433,800 Chief Marketing Officer $207,885 Chief Sales Officer $243,190 Chief Financial Officer $268,455 Senior Strategist $76,105

34

35 Exercise This exercise reinforces the concepts discussed previously. 35

36 Chapter 4: Subqueries 4.1: Noncorrelated Subqueries 4.2: Correlated Subqueries (Self-Study)

37 Objectives Define correlated subqueries. Describe how data is subset using correlated subqueries. 37

38 Correlated Subqueries Correlated subqueries cannot be evaluated independently require values to be passed to the inner query from the outer query are evaluated for each row in the outer query. 38

39 Business Scenario Create a report listing the employee identifier and the first name followed by the last name for all managers in Australia. 39 Considerations: You have a temporary table, Supervisors, containing Employee_ID and Country for all managers. The table orion.Employee_Addresses contains Employee_Name for all employees, but the names are stored as Last, First. You used SCAN() to separate first and last names before. Now you need a new technique to concatenate the pieces into First, Last order.

40 The CATX Function The CATX function concatenates the values in argument-1 through argument-n by stripping leading and trailing spaces, and inserting the value of argument-1 between each segment. General form of the CATX function: delimitera character string that is used as a delimiter between concatenated arguments. argumenta character variable’s name, a character constant, or an expression yielding a character value. 40 CATX(delimiter,argument-1,argument-2 )

41 The CATX Function 41 s104d04a Name ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ John Filo John Kirkman John Hoppmann PROC SQL Output proc sql; select catx(' ',First_name,Last_name) format=$25. as Name from orion.Sales where First_name="John" ; quit; Example:

42 Correlated Subqueries In a correlated subquery, the outer query provides information so that the subquery resolves successfully. 42 proc sql; select Employee_ID, catx(' ',scan(Employee_Name,2), scan(Employee_Name,1) as Manager_Name length=25 from orion.Employee_Addresses where 'AU'= (select Country from Work.Supervisors where Employee_Addresses.Employee_ID= Supervisors.Employee_ID); quit; You must qualify each column with a table name. s104d05

43 Correlated Subqueries 43 Work.Supervisors Employee _ID Country US US AU US US …… US US AU US US US AU Resolves to FALSE... proc sql; select Employee_ID, catx(' ',scan(Employee_Name,2), scan(Employee_Name,1) as Manager_Name length=25 from orion.Employee_Addresses where 'AU'= (select Country from Work.Supervisors where Employee_Addresses.Employee_ID= Supervisors.Employee_ID) ; quit; Partial Listing of orion.Employee_Addresses Employee _ID Employee_Name Aisbitt, Sandy Ardskin, Elizabeth Amos, Salley Billington, Kareen Blackley, James Bleu, Henri Le Cutucache, Chrisy Dawes, Wilson Guscott, Verne Step 1: The outer query takes the first row in orion.Employee_Addresses and finds Employee_ID and Employee_Name.

44 Correlated Subqueries 44 Resolves to FALSE... proc sql; select Employee_ID, catx(' ',scan(Employee_Name,2), scan(Employee_Name,1) as Manager_Name length=25 from orion.Employee_Addresses where 'AU'= (select Country from Work.Supervisors where Employee_Addresses.Employee_ID= Supervisors.Employee_ID) ; quit; orion.Employee_Addresses Employee _ID Employee_Name Aisbitt, Sandy Ardskin, Elizabeth Amos, Salley Billington, Kareen Blackley, James Bleu, Henri Le Cutucache, Chrisy Dawes, Wilson Guscott, Verne Step 2: In the subquery, try to match Employee_Addresses.Employee_ID of with the value of Supervisors.Employee_ID to find a qualifying row in Work.Supervisors. Partial Listing of NO MATCH Work.Supervisors Employee _ID Country US US AU US US …… US US AU US US US AU

45 Correlated Subqueries 45 Work.Supervisors Employee _ID Country US US AU US US …… US US AU US US US AU Resolves to FALSE... proc sql; select Employee_ID, catx(' ',scan(Employee_Name,2), scan(Employee_Name,1) as Manager_Name length=25 from orion.Employee_Addresses where 'AU'= (select Country from Work.Supervisors where Employee_Addresses.Employee_ID= Supervisors.Employee_ID) ; quit; orion.Employee_Addresses Employee _ID Employee_Name Aisbitt, Sandy Ardskin, Elizabeth Amos, Salley Billington, Kareen Blackley, James Bleu, Henri Le Cutucache, Chrisy Dawes, Wilson Guscott, Verne Steps 1 and 2 (Repeat): Read the next row from orion.Employee_Addresses and pass the corresponding employee ID to the subquery to look for a matching employee ID in Work.Supervisors. There is a match. MATCH Partial Listing of

46 Correlated Subqueries 46 Work.Supervisors Employee _ID Country US US AU US US …… US US AU US US US AU Resolves to FALSE... proc sql; select Employee_ID, catx(' ',scan(Employee_Name,2), scan(Employee_Name,1) as Manager_Name length=25 from orion.Employee_Addresses where 'AU'= (select Country from Work.Supervisors where Employee_Addresses.Employee_ID= Supervisors.Employee_ID) ; quit; orion.Employee_Addresses Employee _ID Employee_Name Aisbitt, Sandy Ardskin, Elizabeth Amos, Salley Billington, Kareen Blackley, James Bleu, Henri Le Cutucache, Chrisy Dawes, Wilson Guscott, Verne Step 3: The subquery passes the value of Country from the selected row in Work.Supervisors back to the outer query, where the = operator compares this value to 'AU' for selection in the main query. In this case, the main query WHERE expression ( where 'AU'='US' ) resolves to FALSE. FALSE Partial Listing of Subquery returns 'US'

47

Quiz Given the following query, subquery, and data in Work.Supervisors, what is the maximum number of rows that will be selected by the outer query? 48 proc sql; select Employee_ID, catx(' ',scan(Employee_Name,2), scan(Employee_Name,1) as Manager_Name length=25 from orion.Employee_Addresses where 'AU'= (select Country from Work.Supervisors where Employee_Addresses.Employee_ID= Supervisors.Employee_ID) ; quit; Work.Supervisors Employee _ID Country US US AU US US …… US US AU US US US AU

Quiz – Correct Answer Given the following query, subquery, and data in Work.Supervisors, what is the maximum number of rows that will be selected by the outer query? Only the three managers where Country='AU' would be selected. 49 proc sql; select Employee_ID, catx(' ',scan(Employee_Name,2), scan(Employee_Name,1) as Manager_Name length=25 from orion.Employee_Addresses where 'AU'= (select Country from Work.Supervisors where Employee_Addresses.Employee_ID= Supervisors.Employee_ID) ; quit; Work.Supervisors Employee _ID Country US US AU US US …… US US AU US US US AU

50 The Outer Query Controls the Result Set The outer query determines which rows cause the inner query to resolve successfully. 50 Work.Supervisors Employee _ID Country US US AU US US …… US US AU US US US AU proc sql; select Employee_ID, catx(' ',scan(Employee_Name,2), scan(Employee_Name,1) as Manager_Name length=25 from orion.Employee_Addresses where 'AU'= (select Country from Work.Supervisors where Employee_Addresses.Employee_ID= Supervisors.Employee_ID) ; quit;

51 Correlated Subqueries 51 Resolves to FALSE... proc sql; select Employee_ID, catx(' ',scan(Employee_Name,2), scan(Employee_Name,1) as Manager_Name length=25 from orion.Employee_Addresses where 'AU'= (select Country from Work.Supervisors where Employee_Addresses.Employee_ID= Supervisors.Employee_ID) ; quit; Partial Listing of orion.Employee_Addresses Employee _ID Employee_Name Aisbitt, Sandy Ardskin, Elizabeth Amos, Salley Billington, Kareen Blackley, James Bleu, Henri Le Cutucache, Chrisy Dawes, Wilson Guscott, Verne NO MATCH Continue repeating steps 1, 2, and 3 until all orion.Employee_ Addresses rows are read. Employee_ID has no match. Work.Supervisors Employee _ID Country US US AU US US …… US US AU US US US AU

52 Correlated Subqueries 52 Work.Supervisors Employee _ID Country US US AU US US …… US US AU US US US AU Resolves to FALSE... proc sql; select Employee_ID, catx(' ',scan(Employee_Name,2), scan(Employee_Name,1) as Manager_Name length=25 from orion.Employee_Addresses where 'AU'= (select Country from Work.Supervisors where Employee_Addresses.Employee_ID= Supervisors.Employee_ID) ; quit; orion.Employee_Addresses Employee _ID Employee_Name Aisbitt, Sandy Ardskin, Elizabeth Amos, Salley Billington, Kareen Blackley, James Bleu, Henri Le Cutucache, Chrisy Dawes, Wilson Guscott, Verne MATCH Continue repeating steps 1, 2, and 3 until all rows are read from orion.Employee_Addresses. For Employee_ID , which is passed from the main query to the subquery, there is a match. Partial Listing of

53 Correlated Subqueries 53 Work.Supervisors Employee _ID Country US US AU US US …… US US AU US US US AU Resolves to FALSE... proc sql; select Employee_ID, catx(' ',scan(Employee_Name,2), scan(Employee_Name,1) as Manager_Name length=25 from orion.Employee_Addresses where 'AU'= (select Country from Work.Supervisors where Employee_Addresses.Employee_ID= Supervisors.Employee_ID) ; quit; orion.Employee_Addresses Employee _ID Employee_Name Aisbitt, Sandy Ardskin, Elizabeth Amos, Salley Billington, Kareen Blackley, James Bleu, Henri Le Cutucache, Chrisy Dawes, Wilson Guscott, Verne Subquery returns 'AU' Step 3: The subquery passes the value of Country from the selected row in Work.Supervisors back to the outer query, where the = operator compares this value to 'AU' for selection in the main query. In this case, the main query WHERE expression ( where 'AU'='AU' ) resolves to TRUE. TRUE Partial Listing of

54 Correlated Subqueries 54 Work.Supervisors Employee _ID Country US US AU US US …… US US AU US US US AU Resolves to FALSE... proc sql; select Employee_ID, catx(' ',scan(Employee_Name,2), scan(Employee_Name,1) as Manager_Name length=25 from orion.Employee_Addresses where 'AU'= (select Country from Work.Supervisors where Employee_Addresses.Employee_ID= Supervisors.Employee_ID) ; quit; orion.Employee_Addresses Employee _ID Employee_Name Aisbitt, Sandy Ardskin, Elizabeth Amos, Salley Billington, Kareen Blackley, James Bleu, Henri Le Cutucache, Chrisy Dawes, Wilson Guscott, Verne Partial Listing of Step 4: Write Employee_ID and Manager_Name from orion.Employee_Addresses as the first row in a newly created report.

55 Correlated Subqueries Build the first row of the report: 55 Employee_ID Manager_Name ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ Kareen Billington

56 Correlated Subqueries 56 Work.Supervisors Employee _ID Country US US AU US US …… US US AU US US US AU Resolves to FALSE... proc sql; select Employee_ID, catx(' ',scan(Employee_Name,2), scan(Employee_Name,1) as Manager_Name length=25 from orion.Employee_Addresses where 'AU'= (select Country from Work.Supervisors where Employee_Addresses.Employee_ID= Supervisors.Employee_ID) ; quit; orion.Employee_Addresses Employee _ID Employee_Name Aisbitt, Sandy Ardskin, Elizabeth Amos, Salley Billington, Kareen Blackley, James Bleu, Henri Le Cutucache, Chrisy Dawes, Wilson Guscott, Verne NO MATCH Continue repeating steps 1, 2, and 3 until all orion.Employee_Addresses rows are read. Employee_ID has no match. Partial Listing of

57 Correlated Subqueries 57 Work.Supervisors Employee _ID Country US US AU US US …… US US AU US US US AU Resolves to FALSE... proc sql; select Employee_ID, catx(' ',scan(Employee_Name,2), scan(Employee_Name,1) as Manager_Name length=25 from orion.Employee_Addresses where 'AU'= (select Country from Work.Supervisors where Employee_Addresses.Employee_ID= Supervisors.Employee_ID) ; quit; orion.Employee_Addresses Employee _ID Employee_Name Aisbitt, Sandy Ardskin, Elizabeth Amos, Salley Billington, Kareen Blackley, James Bleu, Henri Le Cutucache, Chrisy Dawes, Wilson Guscott, Verne Steps 1 and 2 (repeated): Read the next row from orion.Employee_Addresses and pass the corresponding employee ID to the subquery to look for a matching employee ID in Work.Supervisors. There is a match. MATCH Partial Listing of

58 Correlated Subqueries 58 Work.Supervisors Employee _ID Country US US AU US US …… US US AU US US US AU Resolves to FALSE... proc sql; select Employee_ID, catx(' ',scan(Employee_Name,2), scan(Employee_Name,1) as Manager_Name length=25 from orion.Employee_Addresses where 'AU'= (select Country from Work.Supervisors where Employee_Addresses.Employee_ID= Supervisors.Employee_ID) ; quit; orion.Employee_Addresses Employee _ID Employee_Name Aisbitt, Sandy Ardskin, Elizabeth Amos, Salley Billington, Kareen Blackley, James Bleu, Henri Le Cutucache, Chrisy Dawes, Wilson Guscott, Verne Subquery returns 'US' Step 3: The subquery passes the value of Country from the selected row in Work.Supervisors back to the outer query, where the = operator compares this value to 'AU' for selection in the main query. In this case, the main query WHERE expression ( where 'AU'='US' ) resolves to FALSE. FALSE Partial Listing of

59 Correlated Subqueries 59 Work.Supervisors Employee _ID Country US US AU US US …… US US AU US US US AU Resolves to FALSE... proc sql; select Employee_ID, catx(' ',scan(Employee_Name,2), scan(Employee_Name,1) as Manager_Name length=25 from orion.Employee_Addresses where 'AU'= (select Country from Work.Supervisors where Employee_Addresses.Employee_ID= Supervisors.Employee_ID) ; quit; orion.Employee_Addresses Employee _ID Employee_Name Aisbitt, Sandy Ardskin, Elizabeth Amos, Salley Billington, Kareen Blackley, James Bleu, Henri Le Cutucache, Chrisy Dawes, Wilson Guscott, Verne Steps 1 and 2 (repeated): Read the next row from orion.Employee_Addresses and pass the corresponding employee ID to the subquery to look for a matching employee ID in Work.Supervisors. There is a match. MATCH Partial Listing of

60 Correlated Subqueries 60 Work.Supervisors Employee _ID Country US US AU US US …… US US AU US US US AU Resolves to FALSE... proc sql; select Employee_ID, catx(' ',scan(Employee_Name,2), scan(Employee_Name,1) as Manager_Name length=25 from orion.Employee_Addresses where 'AU'= (select Country from Work.Supervisors where Employee_Addresses.Employee_ID= Supervisors.Employee_ID) ; quit; orion.Employee_Addresses Employee _ID Employee_Name Aisbitt, Sandy Ardskin, Elizabeth Amos, Salley Billington, Kareen Blackley, James Bleu, Henri Le Cutucache, Chrisy Dawes, Wilson Guscott, Verne Step 3: The subquery passes the value of Country from the selected row in Work.Supervisors back to the outer query, where the = operator compares this value to 'AU' for selection in the main query. In this case, the main query WHERE expression ( where 'AU'='US' ) resolves to FALSE. FALSE Partial Listing of Subquery returns 'US'

61 Correlated Subqueries 61 Work.Supervisors Employee _ID Country US US AU US US …… US US AU US US US AU Resolves to FALSE... proc sql; select Employee_ID, catx(' ',scan(Employee_Name,2), scan(Employee_Name,1) as Manager_Name length=25 from orion.Employee_Addresses where 'AU'= (select Country from Work.Supervisors where Employee_Addresses.Employee_ID= Supervisors.Employee_ID) ; quit; orion.Employee_Addresses Employee _ID Employee_Name Aisbitt, Sandy Ardskin, Elizabeth Amos, Salley Billington, Kareen Blackley, James Bleu, Henri Le Cutucache, Chrisy Dawes, Wilson Guscott, Verne MATCH Continue repeating steps 1, 2, and 3 until all rows are read from orion.Employee_Addresses. For Employee_ID , which is passed from the main query to the subquery, there is a match. Partial Listing of

62 Correlated Subqueries 62 Work.Supervisors Employee _ID Country US US AU US US …… US US AU US US US AU Resolves to FALSE... proc sql; select Employee_ID, catx(' ',scan(Employee_Name,2), scan(Employee_Name,1) as Manager_Name length=25 from orion.Employee_Addresses where 'AU'= (select Country from Work.Supervisors where Employee_Addresses.Employee_ID= Supervisors.Employee_ID) ; quit; orion.Employee_Addresses Employee _ID Employee_Name Aisbitt, Sandy Ardskin, Elizabeth Amos, Salley Billington, Kareen Blackley, James Bleu, Henri Le Cutucache, Chrisy Dawes, Wilson Guscott, Verne Step 3: The subquery passes the value of Country from the selected row in Work.Supervisors back to the outer query, where the = operator compares this value to 'AU' for selection in the main query. In this case, the main query WHERE expression ( where 'AU'='AU' ) resolves to TRUE. TRUE Subquery returns 'AU' Partial Listing of

63 Correlated Subqueries 63 Work.Supervisors Employee _ID Country US US AU US US …… US US AU US US US AU Resolves to FALSE... proc sql; select Employee_ID, catx(' ',scan(Employee_Name,2), scan(Employee_Name,1) as Manager_Name length=25 from orion.Employee_Addresses where 'AU'= (select Country from Work.Supervisors where Employee_Addresses.Employee_ID= Supervisors.Employee_ID) ; quit; orion.Employee_Addresses Employee _ID Employee_Name Aisbitt, Sandy Ardskin, Elizabeth Amos, Salley Billington, Kareen Blackley, James Bleu, Henri Le Cutucache, Chrisy Dawes, Wilson Guscott, Verne Partial Listing of Step 4: Write Employee_ID and Manager_Name from orion.Employee_Addresses as the second row in the report.

64 Correlated Subqueries Build the second row of the report: 64 Employee_ID Manager_Name ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ Kareen Billington Wilson Dawes

65 Correlated Subqueries 65 Work.Supervisors Employee _ID Country US US AU US US …… US US AU US US US AU Resolves to FALSE... proc sql; select Employee_ID, catx(' ',scan(Employee_Name,2), scan(Employee_Name,1) as Manager_Name length=25 from orion.Employee_Addresses where 'AU'= (select Country from Work.Supervisors where Employee_Addresses.Employee_ID= Supervisors.Employee_ID) ; quit; orion.Employee_Addresses Employee _ID Employee_Name Aisbitt, Sandy Ardskin, Elizabeth Amos, Salley Billington, Kareen Blackley, James Bleu, Henri Le Cutucache, Chrisy Dawes, Wilson Guscott, Verne MATCH Continue repeating steps 1, 2, and 3 until all rows are read from orion.Employee_Addresses. For Employee_ID , which is passed from the main query to the subquery, there is a match. Partial Listing of

66 Correlated Subqueries 66 Work.Supervisors Employee _ID Country US US AU US US …… US US AU US US US AU Resolves to FALSE... proc sql; select Employee_ID, catx(' ',scan(Employee_Name,2), scan(Employee_Name,1) as Manager_Name length=25 from orion.Employee_Addresses where 'AU'= (select Country from Work.Supervisors where Employee_Addresses.Employee_ID= Supervisors.Employee_ID) ; quit; orion.Employee_Addresses Employee _ID Employee_Name Aisbitt, Sandy Ardskin, Elizabeth Amos, Salley Billington, Kareen Blackley, James Bleu, Henri Le Cutucache, Chrisy Dawes, Wilson Guscott, Verne Subquery returns 'AU' Step 3: The subquery passes the value of Country from the selected row in Work.Supervisors back to the outer query, where the = operator compares this value to 'AU' for selection in the main query. In this case, the main query WHERE expression ( where 'AU'='AU' ) resolves to TRUE. TRUE Partial Listing of

67 Correlated Subqueries 67 orion.Employee_Addresses Employee _ID Employee_Name Aisbitt, Sandy Ardskin, Elizabeth Amos, Salley Billington, Kareen Blackley, James Bleu, Henri Le Cutucache, Chrisy Dawes, Wilson Guscott, Verne Work.Supervisors Employee _ID Country US US AU US US …… US US AU US US US AU Resolves to FALSE... proc sql; select Employee_ID, catx(' ',scan(Employee_Name,2), scan(Employee_Name,1) as Manager_Name length=25 from orion.Employee_Addresses where 'AU'= (select Country from Work.Supervisors where Employee_Addresses.Employee_ID= Supervisors.Employee_ID) ; quit; Partial Listing of Step 4: Write Employee_ID and Manager_Name from orion.Employee_Addresses as the third row in the report.

68 Correlated Subqueries Build third (and final) row of report: 68 Employee_ID Manager_Name ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ Kareen Billington Wilson Dawes Verne Guscott

69

70 Business Scenario Create a report showing Employee_ID and Job_Title columns of all sales personnel who did not make any sales. The table orion.Sales contains Employee_ID and Job_Title columns for all sales personnel. The table orion.Order_Fact holds information about all sales, and the Employee_ID column contains the employee identifier of the staff member who made the sale. 70

71 The EXISTS and NOT EXISTS Condition The EXISTS condition tests for the existence of a set of values returned by the subquery. The EXISTS condition is true if the subquery returns at least one row. The NOT EXISTS condition is true if the subquery returns no data. 71

72 Correlated Subqueries 72 orion.Order_Fact (all sales)... orion.Sales (all Sales staff )

73 Correlated Subqueries 73 orion.Order_Fact (all sales) Sales made by Sales staff Sales made by non-Sales staff... Sales staff who made no sales orion.Sales (all Sales staff )

74 Correlated Subqueries 74 These are the rows you want. Sales staff who made no sales orion.Sales (all Sales staff )

75 Correlated Subqueries 75 proc sql; select Employee_ID, Job_Title from orion.Sales where not exists (select * from orion.Order_Fact where Sales.Employee_ID= Order_Fact.Employee_ID); The population of Sales staff... s104d06 The table orion.Sales contains the employee IDs, job titles, and other demographic information about the Orion Star Sales staff. orion.Sales

76 Correlated Subqueries 76 proc sql; select Employee_ID, Job_Title from orion.Sales where not exists (select * from orion.Order_Fact where Sales.Employee_ID= Order_Fact.Employee_ID); Staff who placed orders... s104d06 The orion.Order_Fact table contains a row for each product sold to a customer. orion.Order_Fact

77 Correlated Subqueries 77 proc sql; select Employee_ID, Job_Title from orion.Sales where not exists (select * from orion.Order_Fact where Sales.Employee_ID= Order_Fact.Employee_ID); Find Sales employees who exist here... s104d06 …but do not exist here. orion.Sales orion.Order_Fact

78 Testing Concepts: Referencing Columns Are the highlighted column references equivalent? Will they result in the same output? 78 proc sql; select Employee_ID, Job_Title from orion.Sales where not exists (select * from orion.Order_Fact where Sales.Employee_ID = Order_Fact.Employee_ID); quit; proc sql; select Employee_ID, Job_Title from orion.Sales where not exists (select * from orion.Order_Fact where Employee_ID=Employee_ID); quit;

79

80 Setup for the Poll 1.Submit the program s104a02 and review the results. 2.Change the original code to the code shown below. 3.Submit the changed program and review the results. Your instructor will review the log results with you. 80 proc sql; select Employee_ID, Job_Title from orion.Sales where not exists (select * from orion.Order_Fact where Employee_ID=Employee_ID); quit;

Poll Is it necessary to qualify the column names in the inner WHERE clause as follows?  Yes  No 81 where sales.Employee_ID=Order_Fact.Employee_ID

Poll – Correct Answer Is it necessary to qualify the column names in the inner WHERE clause as follows?  Yes  No 82 where sales.Employee_ID=Order_Fact.Employee_ID

83 Correlated Subqueries MATCH proc sql; select Employee_ID, Job_Title from orion.Sales where not exists (select * from orion.Order_Fact where Sales.Employee_ID= Order_Fact.Employee_ID); quit; orion.Sales Employee _ID Job_Title Sales Rep. II Sales Rep. II Sales Manager Sales Rep. I Sales Manager Sales Rep. I... orion.Order_Fact Employee _ID Order _Date Quantity MAY JUN OCT AUG where =120121

84 Correlated Subqueries MATCH proc sql; select Employee_ID, Job_Title from orion.Sales where not exists (select * from orion.Order_Fact where Sales.Employee_ID= Order_Fact.Employee_ID); quit; orion.Sales Employee _ID Job_Title Sales Rep. II Sales Rep. II Sales Manager Sales Rep. I Sales Manager Sales Rep. I... orion.Order_Fact Employee _ID Order _Date Quantity MAY JUN OCT AUG where = The NOT EXISTS clause is FALSE. No output rows are written. FALSE

85 Correlated Subqueries MATCH proc sql; select Employee_ID, Job_Title from orion.Sales where not exists (select * from orion.Order_Fact where Sales.Employee_ID= Order_Fact.Employee_ID); quit; orion.Sales Employee _ID Job_Title Sales Rep. II Sales Rep. II Sales Manager Sales Rep. I Sales Manager Sales Rep. I... orion.Order_Fact Employee _ID Order _Date Quantity MAY JUN OCT AUG where =120122

86 Correlated Subqueries MATCH proc sql; select Employee_ID, Job_Title from orion.Sales where not exists (select * from orion.Order_Fact where Sales.Employee_ID= Order_Fact.Employee_ID); quit; orion.Sales Employee _ID Job_Title Sales Rep. II Sales Rep. II Sales Manager Sales Rep. I Sales Manager Sales Rep. I... orion.Order_Fact Employee _ID Order _Date Quantity MAY JUN OCT AUG where = FALSE The NOT EXISTS clause is FALSE. No output rows are written.

87 Correlated Subqueries 87 NO MATCH... proc sql; select Employee_ID, Job_Title from orion.Sales where not exists (select * from orion.Order_Fact where Sales.Employee_ID= Order_Fact.Employee_ID); quit; orion.Sales Employee _ID Job_Title Sales Rep. II Sales Rep. II Sales Manager Sales Rep. I Sales Manager Sales Rep. I... orion.Order_Fact Employee _ID Order _Date Quantity MAY JUN OCT AUG

88 Correlated Subqueries 88 NO MATCH... proc sql; select Employee_ID, Job_Title from orion.Sales where not exists (select * from orion.Order_Fact where Sales.Employee_ID= Order_Fact.Employee_ID); quit; orion.Sales Employee _ID Job_Title Sales Rep. II Sales Rep. II Sales Manager Sales Rep. I Sales Manager Sales Rep. I... orion.Order_Fact Employee _ID Order _Date Quantity MAY JUN OCT AUG Employee_ID Job_Title ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ Sales Manager Partial PROC SQL Output The NOT EXISTS clause evaluates as TRUE. The first output row is written. TRUE

89 Correlated Subqueries MATCH proc sql; select Employee_ID, Job_Title from orion.Sales where not exists (select * from orion.Order_Fact where Sales.Employee_ID= Order_Fact.Employee_ID); quit; orion.Sales Employee _ID Job_Title Sales Rep. II Sales Rep. II Sales Manager Sales Rep. I Sales Manager Sales Rep. I... orion.Order_Fact Employee _ID Order _Date Quantity MAY JUN OCT AUG where =120123

90 Correlated Subqueries MATCH proc sql; select Employee_ID, Job_Title from orion.Sales where not exists (select * from orion.Order_Fact where Sales.Employee_ID= Order_Fact.Employee_ID); quit; orion.Sales Employee _ID Job_Title Sales Rep. II Sales Rep. II Sales Manager Sales Rep. I Sales Manager Sales Rep. I... orion.Order_Fact Employee _ID Order _Date Quantity MAY JUN OCT AUG where = FALSE The NOT EXISTS clause is FALSE. No output rows are written.

91 Correlated Subqueries 91 NO MATCH... proc sql; select Employee_ID, Job_Title from orion.Sales where not exists (select * from orion.Order_Fact where Sales.Employee_ID= Order_Fact.Employee_ID); quit; orion.Sales Employee _ID Job_Title Sales Rep. II Sales Rep. II Sales Manager Sales Rep. I Sales Manager Sales Rep. I... orion.Order_Fact Employee _ID Order _Date Quantity MAY JUN OCT AUG Employee_ID Job_Title ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ Sales Manager Partial PROC SQL Output

92 Correlated Subqueries 92 NO MATCH... proc sql; select Employee_ID, Job_Title from orion.Sales where not exists (select * from orion.Order_Fact where Sales.Employee_ID= Order_Fact.Employee_ID); quit; orion.Sales Employee _ID Job_Title Sales Rep. II Sales Rep. II Sales Manager Sales Rep. I Sales Manager Sales Rep. I... orion.Order_Fact Employee _ID Order _Date Quantity MAY JUN OCT AUG Employee_ID Job_Title ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ Sales Manager Sales Manager The NOT EXISTS clause evaluates as TRUE. The next output row is written. TRUE Partial PROC SQL Output

93 Correlated Subqueries MATCH proc sql; select Employee_ID, Job_Title from orion.Sales where not exists (select * from orion.Order_Fact where Sales.Employee_ID= Order_Fact.Employee_ID); quit; orion.Sales Employee _ID Job_Title Sales Rep. II Sales Rep. II Sales Manager Sales Rep. I Sales Manager Sales Rep. I... orion.Order_Fact Employee _ID Order _Date Quantity MAY JUN OCT AUG where = FALSE The NOT EXISTS clause is FALSE. No output rows are written.

94 Correlated Subqueries proc sql; select Employee_ID, Job_Title from orion.Sales where not exists (select * from orion.Order_Fact where Sales.Employee_ID= Order_Fact.Employee_ID); quit; orion.Sales Employee _ID Job_Title Sales Rep. II Sales Rep. II Sales Manager Sales Rep. I Sales Manager Sales Rep. I EOF orion.Order_Fact Employee _ID Order _Date Quantity MAY JUN OCT AUG Employee_ID Job_Title ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ Sales Manager Sales Manager When EOF is reached for the table in the outer query, PROC SQL stops processing the query. Partial PROC SQL Output

95

96 Chapter Review True or False: 1.SQL subqueries can return values to be used in an outer query’s FROM clause. 2.A subquery can return several rows of data, but must only return values from a single column. 3.Correlated subqueries use very few resources and are inexpensive to execute. 96

97 Chapter Review Answers True or False: 1.SQL subqueries can return values to be used in an outer query’s FROM clause. False – Subqueries are used only in WHERE and HAVING clauses. 2.A subquery can return several rows of data, but must only return values from a single column. True 3.Correlated subqueries use very few resources and are inexpensive to execute. False – Correlated subqueries are resource intensive and can be very expensive to execute. 97