Appendix B Introduction To SQL
Appendix B Introduction To SQL
Edition
by Raul F. Chong and Clara Liu
IBM Press. (c) 2014. Copying Prohibited.
DB2Essentials:UnderstandingDB2inaBigDataWorld,ThirdEdition
The INSERT, UPDATE, and DELETE SQL statements used to modify table data
How to query data that just got inserted, updated, or deleted in the same SQL statement
The MERGE SQL statement used to combine insert, update, and/or delete operations in one statement
This appendix shows you how to leverage the power of SQL to work with relational data that is stored in DB2 databases;
however most of what is covered here also applies to Big Data through Big SQL. The examples provided in this appendix
use the SAMPLE database.
NoteIf you are following the examples in this appendix using the Command Line Processor (CLP) or the Command
Window, these tools have autocommit enabled by default, so the changes you make are stored permanently to the
table. Refer to Chapter 4, Using Database Tools and Utilities, for more information.
NoteThe purpose of this appendix is to provide you a good introduction to SQL. For more advanced SQL topics, refer
to the DB2 Information Center.
Querying DB2 Data
You use the SELECT statement to query tables or views from a database. At a minimum, the statement contains a SELECT
clause and a FROM clause. The following are two examples of SELECT statements. This first example uses the wildcard
symbol (*) to indicate that all columns from the EMPLOYEE table are selected:
SELECT * FROM employee;
In this example, the column names empno, firstname, and lastname are specified in the SELECT statement:
SELECT empno, firstnme, lastname FROM employee;
Derived Columns
When data is retrieved from a table using the SELECT clause, you can derive or calculate new columns based on other
columns. The DESCRIBE command is handy to display table definitions, which for this section, can help you determine
how to derive other columns based on existing ones. Lets find out what columns are defined in the EMPLOYEE table.
DESCRIBE TABLE employee
IBMPress,InternationalBusinessMachinesCorporation(c)2014,CopyingProhibited
DB2Essentials:UnderstandingDB2inaBigDataWorld,ThirdEdition
DatatypeColumn
ColumnnameschemaDatatypenameLengthScaleNulls
-------------------------------------------------------------EMPNOSYSIBMCHARACTER60No
FIRSTNMESYSIBMVARCHAR120No
MIDINITSYSIBMCHARACTER10Yes
LASTNAMESYSIBMVARCHAR150No
WORKDEPTSYSIBMCHARACTER30Yes
PHONENOSYSIBMCHARACTER40Yes
HIREDATESYSIBMDATE40Yes
JOBSYSIBMCHARACTER80Yes
EDLEVELSYSIBMSMALLINT20No
SEXSYSIBMCHARACTER10Yes
BIRTHDATESYSIBMDATE40Yes
SALARYSYSIBMDECIMAL92Yes
BONUSSYSIBMDECIMAL92Yes
COMMSYSIBMDECIMAL92Yes
14record(s)selected.
Listing B.1 illustrates how to derive the column totalpay by adding the salary and comm columns.
Listing B.1: Example of a Derived Column
SELECTempno,firstnme,lastname,(salary+comm)AStotalpay
FROMemployee
EMPNOFIRSTNMELASTNAMETOTALPAY
--------------------------------------------000010CHRISTINEHAAS156970.00
000020MICHAELTHOMPSON97550.00
000030SALLYKWAN101310.00
000050JOHNGEYER83389.00
000060IRVINGSTERN74830.00
...
Note that totalpay is the name for the derived column specified in the SELECT statement. If it is not specified, DB2 uses the
column number as the column name. In the following example, (salary + comm) is the fourth column in the SELECT list,
hence a number 4 is used as the column name.
SELECT empno, firstnme, lastname, (salary + comm) FROM employee
IBMPress,InternationalBusinessMachinesCorporation(c)2014,CopyingProhibited
DB2Essentials:UnderstandingDB2inaBigDataWorld,ThirdEdition
SELECTDISTINCTregionFROMsales
REGION
--------------Manitoba
Ontario-North
Ontario-South
Quebec
4record(s)selected.
You can also use the DISTINCT clause in the SELECT statement with COUNT function. For example, the SQL statement in
Listing B.4 returns the number of distinct or unique values in the region column of the SALES table.
Listing B.4: Example of a SELECT Statement with COUNT Function and DISTINCT Clause
SELECTCOUNT(DISTINCTregion)FROMsales
1
----------4
1record(s)selected.
The output shows that there are four distinct values for the region column in the SALES table. This value is the same as
we saw with the SELECT DISTINCT region FROM sales result obtained in Listing B.3.
DB2 Special Registers
DB2 special registers are memory values/registers that allow DB2 to provide information to an application about its
environment. These registers can be referenced in SQL statements. Table B.1 lists the most commonly used special
registers. For a complete list of DB2 special registers, refer to the DB2 SQL Reference Guide.
Table B.1: DB2 Special Registers
Page 4 / 19
Reprintedforibm\[email protected],IBM
IBMPress,InternationalBusinessMachinesCorporation(c)2014,CopyingProhibited
DB2Essentials:UnderstandingDB2inaBigDataWorld,ThirdEdition
For example, to display the value of the CURRENT TIMESTAMP special register, issue
VALUES CURRENT TIMESTAMP
SQL also supports expressions using DB2 special registers. Listing B.5 uses the CURRENT DATE register to derive the
retiredate column.
Listing B.5: Example of Using DB2 Special Registers in a SELECT Statement
SELECTempno,firstnme,lastname
,(salary+comm)AStotalpay
,CURRENTDATEASretiredate
FROMemployee
EMPNOFIRSTNMELASTNAMETOTALPAYRETIREDATE
------------------------------------------------------000010CHRISTINEHAAS156970.0010/12/2006
000020MICHAELTHOMPSON97550.0010/12/2006
000030SALLYKWAN101310.0010/12/2006
000050JOHNGEYER83389.0010/12/2006
000060IRVINGSTERN74830.0010/12/2006
...
As indicated in Table B.1, some of the special registers are updatable. For example, to change the value of the CURRENT
ISOLATION special register to RR (Repeatable Read), issue:
SET CURRENT ISOLATION RR
In Listing B.6, the hiredate column is defined with a DATE data type. Invoking the DAYNAME function on the hiredate
column retrieves the name of the day for that date. The function DAYNAME is called a scalar function. A scalar function
takes input values and returns a single value. Another type of function, called a column function, operates on the values of
an entire column. The example in Listing B.7 shows how to calculate the average value of the salary column in the
EMPLOYEE table.
Listing B.7: Example of a Column Function
SELECTDECIMAL(AVG(salary),9,2)ASavgsalary
FROMemployee
Page 5 / 19
Reprintedforibm\[email protected],IBM
IBMPress,InternationalBusinessMachinesCorporation(c)2014,CopyingProhibited
DB2Essentials:UnderstandingDB2inaBigDataWorld,ThirdEdition
AVGSALARY
----------58155.35
1record(s)selected.
The AVG column function, which is a built-in function, calculates the average of a specified column. In this example, it
calculates the average of all the salary values in the EMPLOYEE table. Notice that the DECIMAL function is also used; this
casts the average result to a decimal representation with a precision of 9 and scale of 2. Casting is discussed in the next
section.
The CAST Expression
There are many occasions when a value with a given data type needs to be converted to a different data type. For
example, when manipulating data using the DATE and TIMESTAMP data types, TIMESTAMP might need to be cast to
DATE. Listing B.8 illustrates such an example.
Listing B.8: Example of a CAST Expression
SELECTCURRENTTIMESTAMP,CAST(CURRENTTIMESTAMPASDATE)
FROMSYSIBM.SYSDUMMY1
12
-----------------------------------2006-10-12-12.42.16.82800010/12/2006
1record(s)selected.
DB2 provides many built-in functions you can use. In addition, you can create your own user-defined functions (UDFs). For
more information, refer to the DB2 Information Center.
The FROM Clause
The FROM clause is used to specify the table or tables from where column information will be retrieved. When specifying
multiple tables after FROM, you are dealing with JOIN operations explained later in this appendix. In addition, after a FROM
clause you can enter another SELECT statement or even a function call as long as the output is another table. Later in the
appendix you see examples of this.
The WHERE Clause
For better performance, you should always write your SQL statements so that only the required data is returned. One way
to achieve this is to limit the number of columns to be retrieved by explicitly specifying the column names in the SELECT
statement (as illustrated in previous examples). The other way is to limit the number of rows to be retrieved using the
WHERE clause. Listing B.9 illustrates an example of a SELECT statement that returns employees who are managers with a
salary greater than $1,000.00.
Listing B.9: Example of a WHERE Clause
SELECTempno,firstnme,lastname
FROMemployee
WHEREsalary>1000
ANDjob='MANAGER'
EMPNOFIRSTNMELASTNAME
--------------------------------000020MICHAELTHOMPSON
000030SALLYKWAN
000050JOHNGEYER
000060IRVINGSTERN
000070EVAPULASKI
000090EILEENHENDERSON
000100THEODORESPENSER
7record(s)selected.
Page 6 / 19
Reprintedforibm\[email protected],IBM
IBMPress,InternationalBusinessMachinesCorporation(c)2014,CopyingProhibited
DB2Essentials:UnderstandingDB2inaBigDataWorld,ThirdEdition
Page 7 / 19
Reprintedforibm\[email protected],IBM
IBMPress,InternationalBusinessMachinesCorporation(c)2014,CopyingProhibited
DB2Essentials:UnderstandingDB2inaBigDataWorld,ThirdEdition
FIRSTNMELASTNAMESALARY
-------------------------------------SEANO'CONNELL49250.00
MASATOSHIYOSHIMURA44680.00
JENNIFERLUTZ49840.00
JAMESJEFFERSON42180.00
SALVATOREMARINO48760.00
DANIELSMITH49180.00
SYBILJOHNSON47250.00
WINGLEE45370.00
JASONGOUNOT43840.00
DIANHEMMINGER46500.00
EILEENSCHWARTZ46250.00
11record(s)selected.
The IN Predicate
The IN predicate enables you to search rows based on a set of values. The SQL statement in Listing B.13 returns all the
rows from the SALES table where the value in the sales_date column is either 03/29/1996 or 04/01/2006.
Listing B.13: Example of an IN Predicate
SELECT*FROMsales
WHEREsales_dateIN('03/29/1996','04/01/2006')
SALES_DATESALES_PERSONREGIONSALES
--------------------------------------------------03/29/1996LEEOntario-North2
04/01/2006LUCCHESSIOntario-South3
04/01/2006LUCCHESSIManitoba1
04/01/2006LEEOntario-South8
04/01/2006LEEOntario-North04/01/2006LEEQuebec8
04/01/2006LEEManitoba9
04/01/2006GOUNOTOntario-South3
04/01/2006GOUNOTOntario-North1
04/01/2006GOUNOTQuebec3
04/01/2006GOUNOTManitoba7
11record(s)selected.
Page 8 / 19
Reprintedforibm\[email protected],IBM
IBMPress,InternationalBusinessMachinesCorporation(c)2014,CopyingProhibited
DB2Essentials:UnderstandingDB2inaBigDataWorld,ThirdEdition
You can specify column names or column numbers in the ORDER BY clause, so in the previous query, ORDER BY
lastname ASC could be replaced with ORDER BY 3 ASC.
Notice that LASTNAME is sorted in ascending order. You can explicitly specify the keyword ASC or omit it because it is the
default behavior. To sort the result set in descending order, simply use the DESC keyword instead.
The GROUP BY...HAVING Clause
When you need to group multiple rows into a single row based on one or more columns, the GROUP BY clause comes in
handy. Lets use an example to explain the usage of this clause. Listing B.15 sums up the salary of all the employees. The
GROUP BY clause groups the results by workdept, which returns the total salary of the employees for each department.
The HAVING clause then specifies which of the combined rows are to be retrieved. You can think of it as a WHERE clause
that is applied only to the GROUP BY clause group. In the statement in Listing B.15, only department names starting with E
are retrieved.
Listing B.15: Example of GROUP BY and HAVING Clauses
SELECTworkdept,SUM(salary)AStotal_salary
FROMemployee
GROUPBYworkdept
HAVINGworkdeptLIKE'E%'
WORKDEPTTOTAL_SALARY
----------------------------------------E0180175.00
E11317140.00
E21282520.00
3record(s)selected.
Joins
Sometimes information you want to retrieve does not reside in a single table. You can join the rows in two or more tables in
a SELECT statement by listing the tables in the FROM clause. Consider the example in Listing B.16.
Listing B.16: Example of an INNER Join
SELECTempno,firstnme,lastname,deptname,mgrno
FROMemployee,department
WHEREworkdept=deptno
ANDadmrdept='A00'
EMPNOFIRSTNMELASTNAMEDEPTNAMEMGRNO
------------------------------------------------------------------000010CHRISTINEHAASSPIFFYCOMPUTERSERVICEDIV.000010
000020MICHAELTHOMPSONPLANNING000020
000030SALLYKWANINFORMATIONCENTER000030
000050JOHNGEYERSUPPORTSERVICES000050
000110VINCENZOLUCCHESSISPIFFYCOMPUTERSERVICEDIV.000010
000120SEANO'CONNELLSPIFFYCOMPUTERSERVICEDIV.000010
000130DELORESQUINTANAINFORMATIONCENTER000030
000140HEATHERNICHOLLSINFORMATIONCENTER000030
200010DIANHEMMINGERSPIFFYCOMPUTERSERVICEDIV.000010
200120GREGORLANDOSPIFFYCOMPUTERSERVICEDIV.000010
200140KIMNATZINFORMATIONCENTER000030
11record(s)selected.
Listing B.16 retrieves a list of employees, their department names, and managers employee numbers whose administrative
department (admrdept) is A00. Because the EMPLOYEE table only stores the department number of the employees and
not the department names, you need to join the EMPLOYEE table with the DEPARTMENT table. Note that the two tables
Page 9 / 19
Reprintedforibm\[email protected],IBM
IBMPress,InternationalBusinessMachinesCorporation(c)2014,CopyingProhibited
DB2Essentials:UnderstandingDB2inaBigDataWorld,ThirdEdition
are joined in the FROM clause. Only records with matching department numbers (workdept = deptno) are retrieved.
This type of join is called an inner join; it results in matched rows that are present in both joined tables. The INNER JOIN
keywords can be omitted as demonstrated in Listing B.16. If you choose to explicitly use the INNER JOIN syntax, an
example can be seen at the bottom of Figure B.1, which also illustrates the information that is retrieved when using this
type of join.
There are three other types of joins: LEFT OUTER JOIN, RIGHT OUTER JOIN, and FULL OUTER JOIN. Outer joins
are useful when you want to include rows that are present in the left table, right table, or both tables, in addition to the rows
returned from the implied inner join. A table specified on the left side of the OUTER JOIN operator is considered the left
table, and the table specified on the right side of the OUTER JOIN operator is considered the right table.
A left outer join includes rows from the left table that were missing from the inner join. A right outer join includes rows from
the right table that were missing from the inner join. A full outer join includes rows from both the left and right tables that
were missing from the inner join. Figure B.2, B.3, and B.4 demonstrate information to be retrieved and an example of each
join.
Page 10 / 19
Reprintedforibm\[email protected],IBM
IBMPress,InternationalBusinessMachinesCorporation(c)2014,CopyingProhibited
DB2Essentials:UnderstandingDB2inaBigDataWorld,ThirdEdition
When working with NULL values, the COALESCE function comes in handy: It checks whether the input is NULL and
replaces it with the specified value if it is NULL. See Listing B.17 for an example that returns 0 if the value in the comm
column is NULL.
Listing B.17: Example of the COALESCE Function
SELECTid,name,COALESCE(comm,0)AScomm
FROMstaff
FETCHFIRST6ROWSONLY
IDNAMECOMM
-----------------------------10Sanders0.00
20Pernal612.45
30Marenghi0.00
40O'Brien846.55
50Hanes0.00
60Quigley650.25
6record(s)selected.
IBMPress,InternationalBusinessMachinesCorporation(c)2014,CopyingProhibited
DB2Essentials:UnderstandingDB2inaBigDataWorld,ThirdEdition
expression in an SQL statement to simplify your code. Listing B.18 introduces this expression.
Listing B.18: Example of a CASE Expression
SELECTfirstnme,lastname,
CASE
WHENsalaryISNULLTHEN'Salaryamountismissing'
WHENsalary<=40000THEN'Needaraise'
WHENsalary>40000ANDsalary<=50000THEN'Fairpay'
ELSE'Overpaid'
ENDAScomment
FROMemployee
FIRSTNMELASTNAMECOMMENT
--------------------------------------MAUDESETRIGHTNeedaraise
RAMLALMEHTANeedaraise
WINGLEEFairpay
JASONGOUNOTFairpay
DIANHEMMINGERFairpay
GREGORLANDONeedaraise
KIMNATZOverpaid
KIYOSHIYAMAMOTOOverpaid
...
In Listing B.18, the values of the salary column are evaluated. If the value is less than or equals $40,000, the string Need a
raise is returned. If the value is between $40,000 and $50,000, Fair pay is returned. For all other values, Overpaid is
returned.
Adding a Row Number to the Result Set
Recall that the FETCH FIRST n ROWS ONLY clause enables you to return only the first n rows. What if you want to return
rows higher than 35? The ROWNUMBER and OVER functions solve this problem. Listing B.19 shows a column derived with
sequential row numbers generated by ROWNUMBER() OVER(). Some rows are not displayed in the figure to save space.
Listing B.19: Example 1: Using ROWNUMBER() OVER()
SELECTROWNUMBER()OVER()ASrowid,firstnme,lastnameFROMemployee
ROWIDFIRSTNMELASTNAME
----------------------------------------------1CHRISTINEHAAS
2MICHAELTHOMPSON
3SALLYKWAN
4JOHNGEYER
5IRVINGSTERN
6EVAPULASKI
...
38ROBERTMONTEVERDE
39EILEENSCHWARTZ
40MICHELLESPRINGER
41HELENAWONG
42ROYALONZO
42record(s)selected.
To return rows higher than 35, use the ROWNUMBER()OVER() expression to the FROM clause. Listing B.20 shows this
trick.
Listing B.20: Example 2: Using ROWNUMBER() OVER()
SELECTrowid,firstnme,lastname
FROM(SELECTROWNUMBER()OVER()ASrowid,firstnme,lastname
FROMemployee)AStemp
WHERErowid>35
Page 12 / 19
Reprintedforibm\[email protected],IBM
IBMPress,InternationalBusinessMachinesCorporation(c)2014,CopyingProhibited
DB2Essentials:UnderstandingDB2inaBigDataWorld,ThirdEdition
ROWIDFIRSTNMELASTNAME
----------------------------------------------36KIYOSHIYAMAMOTO
37REBAJOHN
38ROBERTMONTEVERDE
39EILEENSCHWARTZ
40MICHELLESPRINGER
41HELENAWONG
42ROYALONZO
7record(s)selected.
Alternatively, you can explicitly specify the column list for which values are provided in the INSERT statement:
INSERT INTO employee (empno, firstnme, midinit, lastname, edlevel)
VALUES ( '000999', 'SMITH', 'A', 'JOHN', 18 );
For columns that are not named in the INSERT statement, NULL or default value if defined are inserted for a nullable
column. On the other hand if a NOT NULL column has a default value defined, that value will be inserted. Otherwise, the
INSERT fails with SQL0407 Assignment of a NULL value to a NOT NULL column is not allowed.
You can also insert multiple rows in one INSERT statement as shown here:
INSERTINTOemployee(empno,firstnme,midinit,lastname,edlevel)
VALUES('000999','SMITH','A','JOHN',18)
,('000998','LOPEZ','M','JEN',18)
,('000997','FRASER','B','MARC',28)
A multi-row insert can also be achieved with values obtained from a SELECT statement:
INSERT INTO employee_temp ( SELECT * FROM employee );
It is fairly straightforward to update one or more rows in a table by simply assigning the new values in the SET clause of an
UPDATE statement:
UPDATE employee SET salary = salary * 1.5, comm = 0
WHEREempno='000999'
The next UPDATE statement updates the EMPLOYEE table and sets the hiredate with value of the DB2 special register
CURRENT DATE. It also sets the workdept to the department number selected from the DEPARTMENT table.
UPDATEemployee
SET(hiredate,workdept)=(SELECTCURRENTDATE,deptno
FROMdepartment
WHEREdeptname='PLANNING')
WHEREempno='000999'
The DELETE statement is used to delete rows from a table. To remove all rows from the EMPLOYEE table, use the
following statement:
DELETE FROM employee;
To remove only certain rows, use the WHERE clause to filter the rows:
DELETE FROM employee WHERE workdept IS NULL;
To remove rows with a relative position greater than 100 when ordered by empno, use the ROWNUMBER()OVER()
functions like this:
DELETEFROM
(SELECTROWNUMBER()OVER(ORDERBYempno)ASrowid
Page 13 / 19
Reprintedforibm\[email protected],IBM
IBMPress,InternationalBusinessMachinesCorporation(c)2014,CopyingProhibited
DB2Essentials:UnderstandingDB2inaBigDataWorld,ThirdEdition
FROMemployee)
WHERErowid>100
Rather than issuing two separate statements, they can be optimized to use just one SQL statement like this:
SELECTempno,firstnme,lastname
FROMOLDTABLE(DELETEFROMemployeeWHEREworkdept='A00')
The preceding statement deletes the rows and reports to you what was deleted. Because of referential integrity in the
SAMPLE database, this DELETE will not work in this case, but you can practice with this command with other tables of
your own.
Whenever a table is inserted, updated, or deleted, DB2 maintains one or more internal temporal tables known as transition
tables. You specify the transition tables with the NEW TABLE and OLD TABLE clauses. Depending on the SQL operation,
different transition tables are available. Refer to Table B.2 for a summary of their availability.
Table B.2: Availability of Transition Tables Depending on the SQL Statement
Issued
To demonstrate a SELECT from UPDATE query, consider the following example in which you want to increase the salary of
all the employees in department A00. If you use the OLD TABLE clause, you can perform the update and return the old
salaries as they were before the update. This is good for building an audit table to track the changes to important tables.
SELECTsalary
FROMOLDTABLE(UPDATEemployee
SETsalary=salary*1.1
WHEREworkdept='A00')
Similarly, if you want to retrieve the new salary, you can use the NEW TABLE clause instead:
SELECTsalary
FROMNEWTABLE(UPDATEemployee
SETsalary=salary*1.1
WHEREworkdeptISNULL)
NoteThis can now be also achieved with the Time Travel Query feature explained in Chapter 7, Working with
Database Objects.
SELECT from INSERT works just like the preceding example:
SELECTsalary
FROMNEWTABLE(INSERTINTOemployee
(empno,firstnme,midinit,lastname,edlevel,salary)
VALUES('000999','SMITH','A','JOHN',18,45000))
You cannot retrieve the new and old salary values using both the NEW TABLE and OLD TABLE clauses. To do this, use
the INCLUDE clause.
SELECTsalaryasnew_salary,old_salary
Page 14 / 19
Reprintedforibm\[email protected],IBM
IBMPress,InternationalBusinessMachinesCorporation(c)2014,CopyingProhibited
DB2Essentials:UnderstandingDB2inaBigDataWorld,ThirdEdition
FROMNEWTABLE(UPDATEemployeeINCLUDE(old_salaryDECIMAL(9,2))
SETsalary=salary*1.10,
old_salary=salary
WHEREworkdept='A00')
The INCLUDE clause in the nested UPDATE statement creates a new column that can be selected using the outer SELECT
statement. You can see that the old_salary gets the old salary value, and the table column salary is increased by 10
percent.
Finally, lets look at the FINAL TABLE clause. When executing an INSERT, UPDATE, or DELETE statement, there can still
be AFTER triggers or referential constraints that result in further modification of data in the table. Using FINAL TABLE can
prevent these types of changes.
For instance, assume that an AFTER trigger is defined to delete all rows from the EMPLOYEE table when an employees
salary is updated. If FINAL TABLE is used, the UPDATE statement will fails. This protects you from any unforeseen sideeffects not visible to the application.
For example, an error is received if the following SQL statement is issued:
SELECTsalary
FROMFINALTABLE(UPDATEemployee
SETsalary=salary*1.1
WHEREworkdept='A00')
SQL0989NAFTERtrigger"AUDIT_TRIG"attemptedtomodifyarowintable
"EMPLOYEE"thatwasmodifiedbyanSQLdatachangestatementwithinaFROMclause.SQLSTATE=560C3
NoteTrigger is a type of application database object that defines a set of actions to be performed in response to an
insert, update, or delete operation on a specified table. Triggers are discussed in Chapter 7, Working with
Database Objects.
The MERGE Statement
The MERGE statement combines an INSERT statement with an UPDATE or DELETE statement. For example, if a row in
table T1 also exists in table T2, the existing row in T2 should be updated. If a row in T1 does not exist in T2, it should be
inserted into T2. A new and efficient way to code this logic can be implemented with one statement: the MERGE statement.
Listing B.21 shows this MERGE statement.
Listing B.21: Example of a MERGE Statement
MERGEINTOT2astarget
USING(SELECT...FROMT1)ASsource
ONtarget.id=source.id
WHENNOTMATCHEDTHEN
INSERTINTOT2...
WHENMATCHEDTHEN
UPDATET2SET...
Listing B.22 illustrates the syntax of the MERGE statement. The MERGE statement has many clauses; see the DB2 SQL
Reference manual for more examples and additional information.
Listing B.22: Syntax of the MERGE Statement
>>-MERGEINTO--+-table-name-------+---------------------------->
+-view-name--------+
'-(--fullselect--)-'
>--+------------------------+--USING--table-reference---------->
'-|correlation-clause|-'
>--ON--search-condition---------------------------------------->
.----------------------------------------------------------------.
V|
>----WHEN--|matching-condition|--THEN--+-|modification-operation|+>
'-signal-statement---------'
Page 15 / 19
Reprintedforibm\[email protected],IBM
IBMPress,InternationalBusinessMachinesCorporation(c)2014,CopyingProhibited
DB2Essentials:UnderstandingDB2inaBigDataWorld,ThirdEdition
.-ELSEIGNORE-.
>--+-------------+--------------------------------------------><
NoteRefer to Chapter 1, Introduction to DB2, for a description of the DB2 syntax diagram conventions.
The UNION, INTERSECT, and EXCEPT Operators
UNION, INTERSECT, and EXCEPT are operators that can be used to obtain the union, intersection, and difference among
fullselect, subselect, or values-clause. Listing B.23 shows the syntax diagram of the UNION, INTERSECT, and EXCEPT
operators.
Listing B.23: Syntax Diagram of the UNION, INTERSECT, and EXCEPT Operators
>>-+-subselect---------+--------------------------------------->
+-(fullselect)------+
'-|values-clause|-'
.----------------------------------------------.
V|
>----+------------------------------------------+-+------------>
'-+-UNION---------+--+-subselect---------+-'
+-UNIONALL-----++-(fullselect)------+
+-EXCEPT--------+'-|values-clause|-'
+-EXCEPTALL----+
+-INTERSECT-----+
'-INTERSECTALL-'
>--+-----------------+--+--------------------+----------------><
'-order-by-clause-''-fetch-first-clause-'
Listing B.25 shows the results of the UNION and UNION ALL operations on the two tables illustrated in Listing B.24. As
you can see, the UNION operator removes duplicates.
Listing B.25: Examples of UNION and UNION ALL
SELECTR1FROMR1ASR1_UNION_R2
UNIONSELECTR2ASR1_UNION_R2FROMR2
ORDERBYR1_UNION_R2
R1_UNION_R2
-----------------Apple
Banana
Page 16 / 19
Reprintedforibm\[email protected],IBM
IBMPress,InternationalBusinessMachinesCorporation(c)2014,CopyingProhibited
DB2Essentials:UnderstandingDB2inaBigDataWorld,ThirdEdition
Cranberry
Mango
Orange
SELECTR1ASR1_UNION_ALL_R2FROMR1
UNIONALL
SELECTR2ASR1_UNION_ALL_R2FROMR2
ORDERBYR1_UNION_ALL_R2
R1_UNION_ALL_R2
-----------------------Apple
Apple
Apple
Apple
Apple
Banana
Banana
Banana
Banana
Banana
Cranberry
Cranberry
Cranberry
Cranberry
Mango
Orange
IBMPress,InternationalBusinessMachinesCorporation(c)2014,CopyingProhibited
DB2Essentials:UnderstandingDB2inaBigDataWorld,ThirdEdition
SELECTR1ASR1_EXCEPT_R2FROMR1
EXCEPT
SELECTR2ASR1_EXCEPT_R2FROMR2
ORDERBYR1_EXCEPT_R2
R1_EXCEPT_R2
-----------------Mango
SELECTR1ASR1_EXCEPT_ALL_R2FROMR1
EXCEPTALL
SELECTR2ASR1_EXCEPT_ALL_R2FROMR2
ORDERBYR1_EXCEPT_ALL_R2
R1_EXCEPT_ALL_R2
-----------------------Apple
Cranberry
Cranberry
Mango
Page 18 / 19
Reprintedforibm\[email protected],IBM
IBMPress,InternationalBusinessMachinesCorporation(c)2014,CopyingProhibited
DB2Essentials:UnderstandingDB2inaBigDataWorld,ThirdEdition
To retrieve the ancestors of Jenny, you would use the recursive query shown in Listing B.30.
Listing B.30: A Recursive SQL Example
WITHtemptab(person_id,name,parent_id)AS(1)
(SELECTperson_id,name,parent_id(2)
FROMchildren
WHEREname='Jenny'
UNIONALL(3)
SELECTc.person_id,c.name,c.parent_id(4)
FROMchildrenc,temptabsuper
WHEREc.person_id=super.parent_id
)SELECT*FROMtemptab(5)
In Listing B.30, the CTE is called temptab, and it is created with the WITH clause on line (1). The definition of the CTE is
specified at lines (2), (3), and (4) inside the parentheses.
Line (2) obtains the initial result set that contains the record with the name 'Jenny'. Then, the recursion takes place by
joining each row in temptab with its parents (4). The result of one execution of this recursion is added to temptab via
UNION ALL at line (3).
The final query (5) extracts the person_id, name, and parent_id out of the temptab CTE.
The recursive SQL returns Jennys parents and their parents, as shown in Listing B.31.
Listing B.31: Result of a Recursive SQL
PERSON_IDNAMEPARENT_ID
--------------------------------------------------SQL0347WTherecursivecommontableexpression"DB2ADMIN.TEMPTAB"maycontainaninfiniteloop.SQ
6Jenny4
4Mary24
24Robert30
3record(s)selectedwith1warningmessagesprinted.
Notice that a warning message is also returned indicating that the CTE might contain an infinite loop. To avoid an infinite
loop, you can specify the maximum number of recursive levels in the query. For example, in Listing B.32 the maximum
number of recursive levels must be fewer than 5.
Listing B.32: A Recursive SQL Example with a Maximum Number of Recursive Levels
WITHtemptab(person_id,name,parent_id,level)AS
(SELECTperson_id,name,parent_id,1
FROMchildren
WHEREname='Jenny'
UNIONALL
SELECTc.person_id,c.name,c.parent_id,super.level+1
FROMchildrenc,temptabsuper
WHEREc.person_id=super.parent_id
ANDlevel<5
)SELECT*FROMtemptab
Page 19 / 19
Reprintedforibm\[email protected],IBM
IBMPress,InternationalBusinessMachinesCorporation(c)2014,CopyingProhibited