When using group functions or aggregate functions in a query, the columns that do not have any aggregate function applied to them must appear in the GROUP BY clause of the query.. For ex
Trang 1Utilizing Aggregate Functions 181
F single 47
M single 92
married 180
F married 63
M married 117
more Dba Queries In the “Exploring DBA Queries Using Aggregate Functions” sidebar, you saw some que-ries written to find out the space allocated by tablespace, the space allocated by schema, and the space allocated by tablespace and schema These were written using three dif-ferent SQL statements You can see the power of CUBE in the following SQL The results from all the three SQL statements you tried before are in this summary report, showing the different levels of aggregation SELECT tablespace_name, owner, SUM(bytes)/1048576 size_mb FROM dba_segments GROUP BY CUBE (tablespace_name, owner); TABLESPACE_NAME OWNER SIZE_MB - -
1564.8125 <- Grand Total HR 1.75 <- Subtotal HR schema IX 1.625 <- Subtotal IX schema OE 8.875 … … …
FLOWS 100.6875 <- Subtotal FLOWS schema USERS 21.25 <- Subtotal USERS tablespace USERS HR .1875 <- HR schema in USERS tablespace USERS OE 2.625 <- OE schema in USERS tablespace USERS SH 2
USERS SCOTT .375
USERS BTHOMAS 16.0625 SYSAUX 716.375 <- Subtotal SYSAUX tablespace … … …
SYSAUX FLOWS 100.6875 SYSTEM 701.625 <- Subtotal SYSTEM tablespace SYSTEM SYS 685.1875
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Trang 2182 Chapter 3 N Using Group Functions
SYSTEM OUTLN 5625
SYSTEM SYSTEM 15.875 EXAMPLE 77.3125 EXAMPLE HR 1.5625 … … …
As you can see in the result, the space used by each schema in each tablespace is shown as well as the total space used in each tablespace and the total space used by each schema The total space used in the database (including all tablespaces) is also shown in the very first line Three functions come in handy with the ROLLUP and CUBE modifiers of the GROUP BY clause—GROUPING, GROUP_ID, and GROUPING_ID In the examples you have seen using the ROLLUP and CUBE modifiers, there was no way of telling which row is a subtotal and which row is a grand total You can use the GROUPING function to overcome this problem Review the following SQL example: SELECT gender, marital_status, count(*) num_rec, GROUPING (gender) g_grp, GROUPING (marital_status) ms_grp FROM oe.customers GROUP BY CUBE(marital_status, gender); G MARITAL_STATUS NUM_REC G_GRP MS_GRP -
319 1 1
F 110 0 1
M 209 0 1
single 139 1 0
F single 47 0 0
M single 92 0 0
married 180 1 0
F married 63 0 0
M married 117 0 0 The G_GRP column has a 1 for NULL values generated by the CUBE or ROLLUP modifier for GENDER column Similarly, the MS_GRP column has a 1 when NULL values are generated in the MARITAL_STATUS column Using a DECODE function on the result of the GROUPING function, you can produce a more meaningful result set, as in the following example:
SELECT DECODE(GROUPING (gender), 1, ‘Multi-Gender’,
Trang 3Utilizing Aggregate Functions 183
‘Multi-MaritalStatus’, marital_status) marital_status, count(*) num_rec
FROM oe.customers GROUP BY CUBE(marital_status, gender);
GENDER MARITAL_STATUS NUM_REC
-Multi-Gender Multi-MaritalStatus 319
F Multi-MaritalStatus 110
M Multi-MaritalStatus 209
Multi-Gender single 139
F single 47
M single 92
Multi-Gender married 180
F married 63
M married 117
You can use the GROUPING function in the HAVING clause to filter out rows You can display only the summary results using the GROUPING function in the HAVING clause The GROUPING_ID function returns the exact level of the group It is derived from the GROUPING function by concatenating the GROUPING levels together as bits, and gives the GROUPING_ID Review the following example closely to understand this: SELECT gender, marital_status, count(*) num_rec, GROUPING (gender) g_grp, GROUPING (marital_status) ms_grp, GROUPING_ID (gender, marital_status) groupingid FROM oe.customers GROUP BY CUBE(gender, marital_status); G MARITAL_STATUS NUM_REC G_GRP MS_GRP GROUPINGID -
319 1 1 3
single 139 1 0 2
married 180 1 0 2
F 110 0 1 1
F single 47 0 0 0
F married 63 0 0 0
M 209 0 1 1
M single 92 0 0 0
M married 117 0 0 0
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Trang 4184 Chapter 3 N Using Group Functions
In this example, you can clearly identify the level of grouping using the GROUPING_ID function The GROUP_ID function is used to distinguish the duplicate groups In the follow-ing example, the GROUP_ID() value is 1 for duplicate groups When writing complex aggre-gates, you can filter out the duplicate rows by using the HAVING GROUP_ID = 0 clause in the SELECT statement
SELECT gender, marital_status, count(*) num_rec, GROUPING_ID (gender, marital_status) groupingid, GROUP_ID() groupid
FROM oe.customers GROUP BY gender, CUBE(gender, marital_status);
G MARITAL_STATUS NUM_REC GROUPINGID GROUPID
-
-F single 47 0 0
F married 63 0 0
M single 92 0 0
M married 117 0 0
F single 47 0 1
F married 63 0 1
M single 92 0 1
M married 117 0 1
F 110 1 0
M 209 1 0
F 110 1 1
M 209 1 1
Nesting Functions
Functions can be nested so that the output from one function is used as input to another
Operators have an inherent precedence of execution such as * before +, but function precedence is based on position only Functions are evaluated innermost to outermost and left to right This nesting technique is common with some functions, such as DECODE (covered in Chapter 2), where it can be used to implement limited IF…THEN…ELSE logic within a SQL statement
For example, the V$SYSSTAT view contains one row for each of three interesting sort statistics If you want to report all three statistics on a single line, you can use DECODE com-bined with SUM to filter out data in the SELECT clause This filtering operation is usually done in the WHERE or HAVING clause, but if you want all three statistics on one line, you can issue this command:
Trang 5Utilizing Aggregate Functions 185
SUM (DECODE (name,’sorts (disk)’, value,0)) on_disk, SUM (DECODE
(name,’sorts (rows)’, value,0)) rows_sortedFROM v$sysstat;
IN_MEMORY ON_DISK ROWS_SORTED - - -
728 12 326714What happens in the previous statement is a single pass through the V$SYSSTAT table
The presummary result set would have the same number of rows as V$SYSSTAT (232, for instance) Of these 232 rows, all rows and columns have zeros, except for one row in each column that has the data of interest Table 3.3 shows the data that was used in this example
The summation operation then adds all the zeros to your interesting data and gives you the results you want
ta b l e 3 3 Presummarized Result Set
Nesting Single-Row Functions with Group Functions
Nested functions can include single-row functions nested within group functions, as you’ve just seen, or group functions nested within either single-row functions or other group func-tions For example, suppose you need to report on the departments in the EMP table, show-ing either the number of jobs or the number of managers, whichever is greater You would enter the following:
SELECT deptno, GREATEST(
COUNT(DISTINCT job), COUNT(DISTINCT mgr)) cnt, COUNT(DISTINCT job) jobs,
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Trang 6186 Chapter 3 N Using Group Functions
COUNT(DISTINCT mgr) mgrs FROM scott.emp
GROUP BY deptno;
DEPTNO CNT JOBS MGRS
10 3 3 2
20 4 3 4
30 3 3 2
Nesting Group Functions You can also nest group functions within group functions Only one level of nesting is allowed when nesting a group function within a group function To report the maximum number of jobs in a single department, you would query the following: SELECT MAX(COUNT (DISTINCT job_id)) FROM employees GROUP BY department_id; MAX(COUNT(DISTINCTJOB_ID))
3
Group functions can be nested only one level If you try to nest more than one level of nested group functions, you will encounter an error Also, there is no reason to do so Here is an example to show the error, though the SQL does not mean much: SELECT MIN (MAX (COUNT (DISTINCT job_id))) FROM employees GROUP BY department_id; SELECT MIN (MAX (COUNT (DISTINCT job_id))) *
ERROR at line 1:
ORA-00935: group function is nested too deeply
Trang 7Exam Essentials 187
Summary
Though this chapter is small in terms of OCA certification exam content, this chapter is very important for the test It is important to understand the concept of grouping data, where GROUP BY and HAVING clauses can be used, and the rules associated with using these clauses
I started this chapter by discussing the group-function fundamentals and reviewed the group functions by concentrating on the functions that are important for the test
I also discussed how group functions can be used in the SELECT, HAVING, and ORDER BYclauses of SELECT statements Most group functions can be applied to all data values or only to the distinct data values Except for COUNT(*), group functions ignore NULLs Pro-grammer-written functions cannot be used as group functions COUNT, SUM, and AVG are the most commonly used group functions
When using group functions or aggregate functions in a query, the columns that do not have any aggregate function applied to them must appear in the GROUP BY clause of the query
The HAVING clause is used to filter out data after the aggregates are calculated Group tions cannot be used in the WHERE clause
func-You can create superaggregates using the CUBE and ROLLUP modifiers in the GROUP BY clause
Exam Essentials
Understand the usage of DISTINCT in group functions When DISTINCT is specified, only one of each non-NULL value is applied to the function To apply all non-NULL values, the keyword ALL should be used
Know where group functions can be used Group functions can be used in GROUP BY, ORDER BY, and HAVING clauses They cannot be used in WHERE clauses
Know how MIN and MAX sort date and character data Older dates evaluate to lower values,
while newer dates evaluate to higher values Character data, even if it contains numbers, is sorted according to the NLS_SORT specification
Know which expressions in a SELECT list must appear in a GROUP BY clause If any
group-ing is performed, all nongroup function expressions and nonconstant expressions must appear in the GROUP BY clause
Know the order of precedence for evaluating nested functions You may need to
evalu-ate an expression containing nested functions Make sure you understand the left-to-right order of precedence used to evaluate these expressions
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Trang 8A Statement 1 will fail because it is missing a GROUP BY clause.
B Statement 2 will return one row, and statement 1 may return more than one row.
C Statement 2 will fail because it does not have the columns used in the GROUP BY clause
in the SELECT clause
D Statement 1 will display two columns, and statement 2 will display two values for each
state
2 Using the SALES table described here, you need to report the following:
Gross, net, and earned revenue for the second and third quarters of 1999
Û N
Gross, net, and earned revenue for sales in the states of Illinois, California, and
Û N
Texas (codes IL, CA, and TX)
Will all the requirements be met with the following SQL statement?
SELECT state_code, SUM(ALL gross), SUM(net), SUM(earned)FROM sales_detail
WHERE TRUNC(sales_date,’Q’) BETWEEN TO_DATE(’01-Apr-1999’,’DD-Mon-YYYY’) AND TO_DATE(’01-Sep-1999’,’DD-Mon-YYYY’)
Trang 9Review Questions 189
A The statement meets all three requirements.
B The statement meets two of the three requirements.
C The statement meets one of the three requirements.
D The statement meets none of the three requirements.
E The statement will raise an exception.
3 Which line in the following SQL has an error?
1 SELECT department_id, SUM(salary)
4 John is trying to find out the average salary of employees in each department He noticed
that the SALARY column can have NULL values, and he does not want the NULLs included when calculating the average Identify the correct SQL that will produce the desired results
A SELECT department_id, AVG(salary)
FROM employeesGROUP BY department_id;
B SELECT department_id, AVG(NVL(salary,0))
FROM employeesGROUP BY department_id;
C SELECT department_id, NVL(AVG(salary), 0)
FROM employeesGROUP BY department_id;
D SELECT department_id, AVG(salary)
FROM employeesGROUP BY department_idHAVING salary IS NOT NULL;
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Trang 10190 Review Questions
5 Review the following two SQL statements, and choose the appropriate option.
1 SELECT department_id, COUNT(*)FROM employees
HAVING COUNT(*) > 10GROUP BY department_id;
2 SELECT department_id, COUNT(*)FROM employees
WHERE COUNT(*) > 10GROUP BY department_id;
A Statement 1 and statement 2 will produce the same results.
B Statement 1 will succeed, and statement 2 will fail.
C Statement 2 will succeed, and statement 1 will fail.
D Both statements fail.
6 Read the following SQL carefully, and choose the appropriate option The JOB_ID column
shows the various jobs
SELECT MAX(COUNT(*))FROM employees
GROUP BY job_id, department_id;
A Aggregate functions cannot be nested.
B The columns in the GROUP BY clause must appear in the SELECT clause for the query
to work
C The GROUP BY clause is not required in this query.
D The SQL will produce the highest number of jobs within a department
7 Identify the SQL that produces the correct result.
A SELECT department_id, SUM(salary)
FROM employeesWHERE department_id <> 50GROUP BY department_idHAVING COUNT(*) > 30;
B SELECT department_id, SUM(salary) sum_sal
FROM employeesWHERE department_id <> 50GROUP BY department_idHAVING sum_sal > 3000;
Trang 11Review Questions 191
C SELECT department_id, SUM(salary) sum_sal
FROM employeesWHERE department_id <> 50AND sum_sal > 3000
GROUP BY department_id;
D SELECT department_id, SUM(salary)
FROM employeesWHERE department_id <> 50 AND SUM(salary) > 3000GROUP BY department_id;
8 Consider the following SQL, and choose the most appropriate option.
SELECT COUNT(DISTINCT SUBSTR(first_name, 1,1))FROM employees;
A A single-row function nested inside a group function is not allowed.
B The GROUP BY clause is required to successfully run this query.
C Removing the DISTINCT qualifier will fix the error in the query.
D The query will execute successfully without any modification.
9 The sales order number (ORDER_NO) is the primary key in the table SALES_ORDERS Which
query will return the total number of orders in the SALES_ORDERS table?
A SELECT COUNT(ALL order_no) FROM sales_orders;
B SELECT COUNT(DISTINCT order_no) FROM sales_orders;
C SELECT COUNT(order_no) FROM sales_orders;
D SELECT COUNT(NVL(order_no,0) FROM sales_orders;
E All of the above
F A and C
10 Sheila wants to find the highest salary within each department of the EMPLOYEES table
Which query will help her get what she wants?
A SELECT MAX(salary) FROM employees;
B SELECT MAX(salary BY department_id) FROM employees;
C SELECT department_id, MAX(salary) max_sal FROM employees;
D SELECT department_id, MAX(salary) FROM employees GROUP BY department_
id;
E SELECT department_id, MAX(salary) FROM employees USING department_id;
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Trang 12192 Review Questions
11 Which assertion about the following queries is true?
SELECT COUNT(DISTINCT mgr), MAX(DISTINCT salary)FROM emp;
SELECT COUNT(ALL mgr), MAX(ALL salary)FROM emp;
A They will always return the same numbers in columns 1 and 2.
B They may return different numbers in column 1 but will always return the same
num-ber in column 2
C They may return different numbers in both columns 1 and 2.
D They will always return the same number in column 1 but may return different
num-bers in column 2
12 Which clauses in the SELECT statement can use single-row functions nested in aggregate
functions? (Choose all that apply.)
A SELECT
B ORDER BY
C WHERE
D GROUP BY
13 Consider the following two SQL statements Choose the most appropriate option
1. select substr(first_name, 1,1) fn, SUM(salary) FROM employees GROUP BY first_name;
2. select substr(first_name, 1,1) fn, SUM(salary) FROM employees GROUP BY substr(first_name, 1,1);
A Statement 1 and 2 will produce the same result.
B Statement 1 and 2 will produce different results.
C Statement 1 will fail.
D Statement 2 will fail, but statement 1 will succeed.
14 How will the results of the following two SQL statements differ?
Trang 13Review Questions 193
A Statement 1 will return one row, and statement 2 may return more than one row.
B Both statements will fail because they are missing a GROUP BY clause.
C Both statements will return the same results.
D Statement 2 may return a smaller COUNT value than statement 1.
15 Why does the following SELECT statement fail?
SELECT colorname Colour, MAX(cost)FROM itemdetail
WHERE UPPER(colorname) LIKE ‘%WHITE%’
GROUP BY colourHAVING COUNT(*) > 20;
A A GROUP BY clause cannot contain a column alias.
B The condition COUNT(*) > 20 should be in the WHERE clause.
C The GROUP BY clause must contain the group functions used in the SELECT list.
D The HAVING clause can contain only the group functions used in the SELECT list.
16 What will the following SQL statement return?
select max(prod_pack_size)from sh.products
where min(prod_weight_class) = 5;
A An exception will be raised.
B The largest PROD_PACK_SIZE for rows containing PROD_WEIGHT_CLASS of 5 or higher
C The largest PROD_PACK_SIZE for rows containing PROD_WEIGHT_CLASS of 5
D The largest PROD_PACK_SIZE in the SH.PRODUCTS table
17 Why will the following query raise an exception?
select dept_no, avg(distinct salary), count(job) job_count
from empwhere mgr like ‘J%’
or abs(salary) > 10having count(job) > 5order by 2 desc;
A The HAVING clause cannot contain a group function.
B The GROUP BY clause is missing.
C ABS() is not an Oracle function.
D The query will not raise an exception.
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Trang 14194 Review Questions
18 Which clause will generate an error when the following query is executed?
SELECT department_id, AVG(salary) avg_salFROM employees
GROUP BY department_idHAVING TRUNC(department_id) > 50;
A The GROUP BY clause, because it is missing the group function.
B The HAVING clause, because single-row functions cannot be used.
C The HAVING clause, because the AVG function used in the SELECT clause is not used in
the HAVING clause
D None of the above The SQL statement will not return an error.
19 Which statements are true? (Choose all that apply.)
A A group function can be used only if the GROUP BY clause is present.
B Group functions along with nonaggregated columns can appear in the SELECT clause
as long as a GROUP BY clause and a HAVING clause are present
C The HAVING clause is optional when the GROUP BY clause is used.
D The HAVING clause and the GROUP BY clause are mutually exclusive; you can use only
one clause in a SELECT statement
20 Read the following two statements, and choose the best option.
1. HAVING clause should always appear after the GROUP BY clause
2. GROUP BY clause should always appear after the WHERE clause
A Statement 1 and 2 are false.
B Statement 1 is true, and statement 2 is false.
C Statement 1 is false, and statement 2 is true.
D Statements 1 and 2 are true.
Trang 15Answers to Review Questions 195
Answers to Review Questions
1 D Though you do not have a state column in the SELECT clause, having it in the GROUP
BY clause will group the results by state, so you end up getting two values (two columns) for each state
2 A All requirements are met The gross-, net-, and earned-revenue requirements are
satis-fied with the SELECT clause The second- and third-quarter sales requirement is satissatis-fied with the first predicate of the WHERE clause—the sales date will be truncated to the first day
of a quarter; thus, 01-Apr-1999 or 01-Jul-1999 for the required quarters (which are both between 01-Apr-1999 and 01-Sep-1999) The state codes requirement is satisfied by the second predicate in the WHERE clause This question is intentionally misleading, but so are some exam questions (and, unfortunately, some of the code in some shops)
3 C Since the department_id column does not have any aggregate function applied to it,
it must appear in the GROUP BY clause The ORDER BY clause in the SQL must be replaced with a GROUP BY clause to make the query work
4 A Since group functions do not include NULL values in their calculation, you do not have to
do anything special to exclude the NULL values Only COUNT(*) includes NULL values
5 B An aggregate function is not allowed in the WHERE clause You can have the GROUP BY
and HAVING clauses in any order, but they must appear after the WHERE clause
6 D The SQL will work fine and produce the result Since group functions are nested, a
GROUP BY clause is required
7 A It is perfectly alright to have one function in the SELECT clause and another function in
the HAVING clause of the query Options B and C are trying to use the alias name, which is not allowed Option D has a group function in the WHERE clause, which is also not allowed
8 D The query will return how many distinct alphabets are used to begin names in the
EMPLOYEES table You can nest a group function inside a single-row function, and vice versa
9 E All the queries will return the same result Since ORDER_NO is the primary key, there cannot
be NULL values in the column Hence, ALL and DISTINCT will give the same result
10 D Option A will display the highest salary of all the employees Options B and E use
invalid syntax keywords Option C does not have a GROUP BY clause
11 B The first column in the first query is counting the distinct MGR values in the table The first
column in the second query is counting all MGR values in the table If a manager appears twice, the first query will count her one time, but the second will count her twice Both the first query and the second query are selecting the maximum salary value in the table
12 A, B A group function is not allowed in GROUP BY or WHERE clauses, whether you use it as
nested or not
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Trang 16196 Chapter 3 N Using Group Functions
13 B Both statements are valid The first statement will produce the number of rows equal to
the number of unique first_name values The second statement will produce the number of rows equal to the unique number of first characters in the first_name column
14 D COUNT(*) will count all rows in the table COUNT(salary) will count only the number
of salary values that appear in the table If there are any rows with a NULL salary, ment 2 will not count them
state-15 A A GROUP BY clause must contain the column or expressions on which to perform the
grouping operation It cannot use column aliasing
16 A You cannot place a group function in the WHERE clause Instead, you should use a
HAVING clause
17 B There is at least one column in the SELECT list that is not a constant or group function,
so a GROUP BY clause is mandatory
18 D The HAVING clause filters data after the group function is applied If an aggregate
func-tion is not used in the HAVING clause, the column used must be part of the SELECT clause
19 C The HAVING clause can be used in a SELECT statement only if the GROUP BY clause is
present The optional HAVING clause filters data after the rows are summarized
20 C The GROUP BY and HAVING clauses can appear in any order in the SELECT clause If a
WHERE clause is present, it must be before the GROUP BY clause
Trang 17Û N
table using equijoins and nonequijoinsJoin a table to itself by using a self-join
Û N
View data that generally does not meet a join condition by
Û N
using outer joinsGenerate a Cartesian product of all rows from two or
Û N
more tables
Using subqueries to solve queries
ÛÛDefine subqueries
Û N
Describe the types of problems that the subqueries can solve
Û N
List the types of subqueries
Û N
Write single-row and multiple-row subqueries
Û N
Using the Set operators
ÛÛDescribe set operators
Û N
Use a set operator to combine multiple queries into a
Û N
single queryControl the order of rows returned
Û N
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Trang 18A database has many tables that store data In Chapter 1,
“Introducing SQL,” you learned how to write simple queries that select data from one table Although this information is essential to passing the certification exam, the ability to join two or more related tables and access information is the core strength of relational databases Using the SELECT statement, you can write advanced queries that satisfy user requirements
This chapter focuses on querying data from more than one table using table joins and subqueries When you use two or more tables or views in a single query, it is a join query
You’ll need to understand how the various types of joins and subqueries work, as well as the proper syntax, for the certification exam
Set operators in Oracle let you combine results from two or more SELECT statements
The results of each SELECT statement are considered a set, and Oracle provides UNION, INTERSECT, and MINUS operators to get the desired results You will learn how these opera-tors work in this chapter
Writing Multiple-Table Queries
In relational database management systems (RDBMSs), related data can be stored in tiple tables You use the power of SQL to relate the information and query data A SELECTstatement has a mandatory SELECT clause and FROM clause The SELECT clause can have
mul-a list of columns, expressions, functions, mul-and so on The FROM clause tells you in which table(s) to look for the required information In Chapter 1, you learned to query data using simple SELECT statements from a single table In this chapter, you will learn how to retrieve data from more than one table
To query data from more than one table, you need to identify common columns that relate the two tables Here’s how you do it:
1. In the SELECT clause, you list the columns you are interested in from all the related tables
2. In the FROM clause, you include all the table names separated by commas
3. In the WHERE clause, you define the relationship between the tables listed in the FROMclause using comparison operators
You can also specify the relationship using a JOIN clause instead of the WHERE clause The
Trang 19Writing Multiple-Table Queries 199
SQL1999 standard Throughout this section, you’ll see examples of queries using the cle native syntax as well as the ISO/ANSI SQL1999 standard A query from multiple tables without a relationship or common column is known as a Cartesian join or cross join and is discussed later in this chapter
Ora-A join is a query that combines rows from two or more tables or views Oracle performs
a join whenever multiple tables appear in the query’s FROM clause The query’s SELECT clause can have the columns or expressions from any or all of these tables
If multiple tables have the same column names, the duplicate column names should be qualified in the queries with their table name or table alias
Inner Joins
Inner joins return only the rows that satisfy the join condition The most common operator used to relate two tables is the equality operator (=) If you relate two tables using an equal-
ity operator, it is an equality join, also known as an equijoin This type of join combines
rows from two tables that have equivalent values for the specified columns
Simple Inner Joins
A simple inner join has only the join condition specified, without any other filtering tions For example, let’s consider a simple join between the DEPARTMENTS and LOCATIONStables of the HR schema The common column in these tables is LOCATION_ID You will query these tables to get the location ID, city name, and department names in that city:
condi-SELECT locations.location_id, city, department_nameFROM locations, departments
WHERE locations.location_id = departments.location_id;
Here, you are retrieving data from two tables—two columns from the LOCATIONS table and one column from the DEPARTMENTS table These two tables are joined in the WHERE clause using an equality operator on the LOCATION_ID column It is not necessary for the column names in both tables to have the same name to have a join Notice that the LOCATION_IDcolumn is qualified with its table name for every occurrence This is to avoid ambiguity; it is not necessary to qualify each column, but it increases the readability of the query If the same column name appears in more than one table used in the query, you must qualify the column name with the table name or table alias
To execute a join of three or more tables, Oracle takes these steps:
1. Oracle joins two of the tables based on the join conditions, comparing their columns
2. Oracle joins the result to another table, based on join conditions
3. Oracle continues this process until all tables are joined into the result
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Trang 20200 Chapter 4 N Using Joins and Subqueries
Complex Inner Joins
Apart from specifying the join condition in the WHERE clause, you may have another condition
to limit the rows retrieved Such joins are known as complex joins For example, to
con-tinue with the example in the previous section, if you are interested only in the departments that are outside the United States, use this query:
SELECT locations.location_id, city, department_nameFROM locations, departments
WHERE locations.location_id = departments.location_idAND country_id != ‘US’;
LOCATION_ID CITY DEPARTMENT_NAME - - -
1800 Toronto Marketing
2400 London Human Resources
2700 Munich Public Relations
2500 Oxford Sales
Using Table Aliases
Like columns, tables can have alias names Table aliases increase the readability of the query
You can also use them to shorten long table names with shorter alias names Specify the
table alias name next to the table, separated with a space You can rewrite the query in the
previous section using alias names, as follows:
SELECT l.location_id, city, department_nameFROM locations l, departments d
WHERE l.location_id = d.location_idAND country_id != ‘US’;
When tables (or views or materialized views) are specified in the FROM clause, Oracle looks for the object in the schema (or user) connected to the database If the table belongs
to another schema, you must qualify it with the schema name (You may avoid this by using synonyms, which are discussed in Chapter 7, “Creating Schema Objects.”) You can use the schema owner to qualify a table; you can also use the table owner and schema owner to qualify a column Here is an example:
SELECT locations.location_id, hr.locations.city ,department_name
FROM hr.locations, hr.departmentsWHERE locations.location_id = departments.location_id;
Keep in mind that you can qualify a column name with its schema and table only when
Trang 21Writing Multiple-Table Queries 201
CITY with the schema HR This is possible only if you qualify the LOCATIONS table with the schema The following SQL will produce an error:
SELECT locations.location_id, hr.locations.city ,department_name
FROM locations, hr.departmentsWHERE locations.location_id = departments.location_id;
SELECT locations.location_id, hr.locations.city *
ERROR at line 1:
ORA-00904: “HR”.”LOCATIONS”.”CITY”: invalid identifierWhen you use table alias names, you must qualify the column names with the alias name only; qualifying the columns with the table name will produce an error, as in this example:
SELECT locations.location_id, city, department_nameFROM locations l, hr.departments d
WHERE locations.location_id = d.location_id;
WHERE locations.location_id = d.location_id *
ERROR at line 3:
ORA-00904: “LOCATIONS”.”LOCATION_ID”: invalid identifierThe correct syntax is to replace locations.location_id with l.location_id in the SELECT and WHERE clauses
If there are no common column names between the two tables used in the join (the FROMclause), you don’t need to qualify the columns However, if you qualify the columns, you are telling the Oracle database engine where exactly to find the column; hence, you are improving the performance of the query
If there are column names common to multiple tables used in a join query, you must qualify the column name with a table name or table alias This is true for column names appearing in SELECT, WHERE, ORDER BY, GROUP BY, and HAVING clauses When using the ANSI syntax, the rule is different The ANSI syntax is discussed in the next section
When joining columns using the traditional syntax or ANSI syntax, if the column datatypes are different, Oracle tries to perform an implicit data-type conversion This may affect your query performance It is better if the columns used in the join condition have the same datatype or if you use the explicit conversion functions you learned in Chapter 2, “Using Single-Row Functions.”
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Trang 22202 Chapter 4 N Using Joins and Subqueries
Using the ANSI Syntax
The difference between traditional Oracle join syntax and the ANSI/ISO SQL1999 syntax
is that in ANSI, the join type is specified explicitly in the FROM clause Using the ANSI tax is clearer and is recommended over the traditional Oracle syntax Simple joins can have the following forms:
syn-<table name> NATURAL [INNER] JOIN syn-<table name>
<table name> [INNER] JOIN <table name> USING (<columns>)
<table name> [INNER] JOIN <table name> ON <condition>
The following sections discuss each of the syntax forms in detail In all three syntaxes, the keyword INNER is optional and is the default
NATURAL JOIN
The NATURAL keyword indicates a natural join, where the join is based on all columns that have
same name in both tables In this type of join, you should not qualify the column names with the table name or table alias name Let’s return to the example of querying the DEPARTMENTSand LOCATIONS tables using LOCATION_ID as the join column The new Oracle syntax is as follows:
SELECT location_id, city, department_nameFROM locations NATURAL JOIN departments;
The common column in these two tables is LOCATION_ID, and that column is used to join the tables When specifying NATURAL JOIN, the columns with the same name in both tables should also have same datatype The following query will return the same results:
SELECT location_id, city, department_nameFROM departments NATURAL JOIN locations;
Notice that even though the LOCATION_ID column is in both tables, you did not qualify this column in the SELECT clause You cannot qualify the column names used for the join when using the NATURAL JOIN clause The following query will result in an error:
SELECT l.location_id, city, department_nameFROM departments NATURAL JOIN locations l;
SELECT l.location_id, city, department_name *
ERROR at line 1:
ORA-25155: column used in NATURAL join cannot have qualifierThe following query will not return an error because the qualifier is used on a column that’s not part of the join condition:
Trang 23Writing Multiple-Table Queries 203
If you use SELECT *, common columns are listed only once in the result set The following example demonstrates this The common column in the COUNTRIES table and the REGIONStable is the REGION_ID
SQL> DESCRIBE regions Name Null? Type - - - REGION_ID NOT NULL NUMBER REGION_NAME VARCHAR2(25)
SQL> DESCRIBE countries Name Null? Type - - - COUNTRY_ID NOT NULL CHAR(2) COUNTRY_NAME VARCHAR2(40) REGION_ID NUMBER
SELECT *FROM regions NATURAL JOIN countries;
REGION_ID REGION_NAME CO COUNTRY_NAME - - -
1 Europe UK United Kingdom
1 Europe NL Netherlands
1 Europe IT Testing Update
1 Europe FR France
… … …Here is another example, which joins three tables:
SELECT region_id, region_name, country_id, country_name, location_id, city
FROM regionsNATURAL JOIN countriesNATURAL JOIN locations;
When specifying more than two tables using NATURAL JOIN syntax, it is a good idea to use parentheses to increase readability The previous SQL can be interpreted in two ways:
Trang 24204 Chapter 4 N Using Joins and Subqueries
If you do not use parentheses, Oracle uses left associativity by pairing the tables from left to right (as in the first scenario) By using parentheses, you can make the query less ambiguous, as shown here:
SELECT region_id, region_name, country_id, country_name, location_id, city
FROM locationsNATURAL JOIN (regionsNATURAL JOIN countries);
The same query written in traditional Oracle syntax is as follows:
SELECT regions.region_id, region_name, countries.country_id, country_name, location_id, city
FROM regions, countries, locationsWHERE regions.region_id = countries.region_idAND countries.country_id = locations.country_id;
Though NATURAL JOIN syntax is easy to read and use, its usage should be discouraged in good coding practice Since NATURAL JOIN joins the tables
by all the identical column names, you could end up having a wrong join condition if you’re not careful It is always better to explicitly specify the join condition using the syntaxes available
JOIN…USING
If there are many columns that have the same names in the tables you are joining and they
do not have the same datatype, or you want to specify the columns that should be ered for an equijoin, you can use the JOIN…USING syntax The USING clause specifies the col-umn names that should be used to join the tables Here is an example:
consid-SELECT location_id, city, department_nameFROM locations JOIN departments USING (location_id);
The column names used in the USING clause should not be qualified with a table name or table alias The column names not appearing in the USING clause can be qualified If there are other common column names in the tables and if those column names are used in the query, they must be qualified
Let’s consider this syntax with joining more than two tables:
SELECT region_name, country_name, cityFROM regions
JOIN countries USING (region_id)JOIN locations USING (country_id);
Trang 25Writing Multiple-Table Queries 205
The following query will result in an error because there is no common column between the REGIONS and LOCATIONS tables:
SELECT region_name, country_name, cityFROM regions
JOIN locations USING (country_id)JOIN countries USING (region_id);
JOIN locations USING (country_id) *
ERROR at line 3:
ORA-00904: “REGIONS”.”COUNTRY_ID”: invalid identifierYou can add a WHERE clause to limit the number of rows and an ORDER BY clause to sort the rows retrieved along with any type of join operation:
SELECT region_name, country_name, cityFROM regions
JOIN countries USING (region_id)JOIN locations USING (country_id)WHERE country_id = ‘US’
ORDER BY 1;
Remember that you cannot use alias or table names to qualify the column names on the columns used in the join operation anywhere in the query when using the NATURAL JOIN or JOIN USING syntax You may see ques-tions in the certification exam testing this rule
JOIN…ON
When you do not have common column names between tables to make a join or if you want to specify arbitrary join conditions, you can use the JOIN…ON syntax This syntax specifically defines the join condition using the column names You can qualify column names with a table name or alias name If the column name is common to multiple tables involved in the query, those column names must be qualified
Using the JOIN ON syntax over the traditional join method separates the table joins from the other conditions Since this syntax explicitly states the join condition, it is easier to read and understand Here is the three-table example you used in the previous section, written using the JOIN…ON syntax Notice the use of qualifier on the COUNTRY_ID column; this is required because COUNTRY_ID appears in COUNTRIES and LOCATIONS tables
SELECT region_name, country_name, cityFROM regions r
JOIN countries c ON r.region_id = c.region_idJOIN locations l ON c.country_id = l.country_idWHERE c.country_id = ‘US’;
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.