DB2 SQL Examples
DB2 SQL Examples
DB2 SQL Examples
5
***********************************************************************
EMP_NM
EMP_JB
+----------+ +--------+
|ID|NAME
| |ID|JOB |
|--|-------| |--|-----|
|10|Sanders| |10|Sales|
|20|Pernal | |20|Clerk|
|50|Hanes | +--------+
+----------+
Figure 1, Join example
SELECT
nm.id
,nm.name
,jb.job
FROM
emp_nm nm
,emp_jb jb
WHERE
nm.id = jb.id
ORDER BY 1;
ANSWER
================
ID NAME
JOB
-- ------- ----10 Sanders Sales
20 Pernal Clerk
***********************************************************************
EMP_NM
EMP_JB
SELECT
nm.id
+----------+ +--------+
,nm.name
|ID|NAME
| |ID|JOB |
,jb.job
|--|-------| |--|-----|
FROM
emp_nm nm
|10|Sanders| |10|Sales|
LEFT OUTER JOIN
|20|Pernal | |20|Clerk|
emp_jb jb
|50|Hanes | +--------+
ON
nm.id = jb.id
+----------+
ORDER BY nm.id;
Figure 2,Left-outer-join example
ANSWER
================
ID NAME
JOB
-- ------- ----10 Sanders Sales
20 Pernal Clerk
50 Hanes
-
***********************************************************************
EMP_NM
EMP_JB
SELECT
*
+----------+ +--------+
FROM
emp_nm nm
|ID|NAME
| |ID|JOB |
WHERE NOT EXISTS
|--|-------| |--|-----|
(SELECT *
|10|Sanders| |10|Sales|
FROM
emp_jb jb
|20|Pernal | |20|Clerk|
WHERE nm.id = jb.id)
|50|Hanes | +--------+
ORDER BY id;
+----------+
Figure 3, Sub-query example
ANSWER
========
ID NAME
== =====
50 Hanes
***********************************************************************
EMP_NM
EMP_JB
+----------+ +--------+
|ID|NAME
| |ID|JOB |
|--|-------| |--|-----|
|10|Sanders| |10|Sales|
|20|Pernal | |20|Clerk|
|50|Hanes | +--------+
+----------+
Figure 4, Union example
SELECT
FROM
WHERE
UNION
SELECT
FROM
ORDER BY
*
emp_nm
name < 'S'
*
emp_jb
1,2;
ANSWER
=========
ID 2
-- -----10 Sales
20 Clerk
20 Pernal
50 Hanes
***********************************************************************
EMP_JB
SELECT
id
+--------+
,job
|ID|JOB |
,ROW_NUMBER() OVER(ORDER BY job) AS R
|--|-----|
FROM
emp_jb
|10|Sales|
ORDER BY job;
|20|Clerk|
+--------+
Figure 5, Assign row-numbers example
ANSWER
==========
ID JOB
R
-- ----- 20 Clerk 1
10 Sales 2
***********************************************************************
EMP_JB
+--------+
|ID|JOB |
|--|-----|
|10|Sales|
|20|Clerk|
+--------+
SELECT
id
,job
,CASE
WHEN job = 'Sales'
THEN 'Fire'
ELSE 'Demote'
END AS STATUS
FROM
emp_jb;
Figure 6, Case stmt example
ANSWER
===============
ID JOB
STATUS
-- ----- -----10 Sales Fire
20 Clerk Demote
***********************************************************************
FAMILY
+-----------+
|PARNT|CHILD|
|-----|-----|
|GrDad|Dad |
|Dad |Dghtr|
|Dghtr|GrSon|
|Dghtr|GrDtr|
+-----------+
ANSWER
=========
PERSN LVL
----- --Dad
1
Dghtr
2
GrSon
3
GrDtr
3
***********************************************************************
INPUT DATA
=================
"Some silly text"
Recursive SQL
============>
ANSWER
===========
TEXT LINE#
----- ----Some
1
silly
2
text
3
ANSWER
=================
"Some silly text"
***********************************************************************
EMP_NM
SELECT
*
+----------+
FROM
emp_nm
|ID|NAME
|
ORDER BY id DESC
|--|-------|
FETCH FIRST 2 ROWS ONLY;
|10|Sanders|
|20|Pernal |
|50|Hanes |
+----------+
Figure 10, Fetch first "n" rows example
ANSWER
=========
ID NAME
-- -----50 Hanes
20 Pernal
***********************************************************************
EMP_NM
SELECT
*
+----------+
FROM
emp_nm
|ID|NAME
|
WHERE
name like 'S%'
|--|-------|
WITH UR;
|10|Sanders|
|20|Pernal |
|50|Hanes |
+----------+
Figure 11, Fetch WITH UR example
ANSWER
==========
ID NAME
-- ------10 Sanders
***********************************************************************
EMP_NM
SELECT
AVG(id)
AS avg
+----------+
,MAX(name) AS maxn
|ID|NAME
|
,COUNT(*) AS #rows
|--|-------|
FROM
emp_nm;
|10|Sanders|
|20|Pernal |
|50|Hanes |
+----------+
Figure 12, Column Functions example
ANSWER
=================
AVG MAXN
#ROWS
--- ------- ----26 Sanders
3
***********************************************************************
SELECT
job
,dept
,SUM(salary) AS sum_sal
,COUNT(*)
AS #emps
FROM
staff
WHERE
dept
< 30
AND
salary < 20000
AND
job
< 'S'
GROUP BY ROLLUP(job, dept)
ORDER BY job
,dept;
Figure 13, Subtotal and Grand-total example
ANSWER
=======================
JOB
DEPT SUM_SAL #EMP
----- ---- -------- ---Clerk
15 24766.70
2
Clerk
20 27757.35
2
Clerk
- 52524.05
4
Mgr
10 19260.25
1
Mgr
20 18357.50
1
Mgr
- 37617.75
2
- 90141.80
6
***********************************************************************
--#SET
SELECT
--#SET
SELECT
Figure
DELIMITER !
name FROM staff WHERE id = 10!
DELIMITER ;
name FROM staff WHERE id = 20;
15, Set Delimiter example
***********************************************************************
CREATE TABLE employee
(empno
CHARACTER (00006)
,firstnme VARCHAR
(00012)
,midinit
CHARACTER (00001)
,lastname VARCHAR
(00015)
,workdept CHARACTER (00003)
,phoneno
CHARACTER (00004)
,hiredate DATE
,job
CHARACTER (00008)
,edlevel
SMALLINT
,SEX
CHARACTER (00001)
,birthdate DATE
,salary
DECIMAL
(00009,02)
NOT
NOT
NOT
NOT
NULL
NULL
NULL
NULL
NOT NULL
,bonus
DECIMAL
(00009,02)
,comm
DECIMAL
(00009,02)
)
DATA CAPTURE NONE;
Figure 16, DB2 sample table - EMPLOYEE
***********************************************************************
CREATE VIEW employee_view AS
SELECT
a.empno, a.firstnme, a.salary, a.workdept
FROM
employee a
WHERE
a.salary >=
(SELECT AVG(b.salary)
FROM
employee b
WHERE a.workdept = b.workdept);
Figure 17, DB2 sample view - EMPLOYEE_VIEW
***********************************************************************
CREATE VIEW silly (c1, c2, c3)
AS VALUES (11, 'AAA', SMALLINT(22))
,(12, 'BBB', SMALLINT(33))
,(13, 'CCC', NULL);
Figure 18, Define a view using a VALUES clause
***********************************************************************
SELECT
c1, c2, c3
FROM
silly
ORDER BY c1 aSC;
ANSWER
===========
C1 C2
C3
-- --- -11 AAA 22
12 BBB 33
13 CCC
-
Figure 19, SELECT from a view that has its own data
***********************************************************************
CREATE VIEW test_data AS
WITH temp1 (num1) AS
(VALUES (1)
UNION ALL
SELECT num1 + 1
FROM
temp1
WHERE
num1 < 10000)
SELECT *
FROM
temp1;
Figure 20, Define a view that creates data on the fly
***********************************************************************
CREATE ALIAS
COMMIT;
CREATE ALIAS
COMMIT;
***********************************************************************
CREATE NICKNAME emp FOR unixserver.production.employee;
Figure 22, Define a nickname
***********************************************************************
SELECT
*
FROM
staff TABLESAMPLE BERNOULLI(10);
Figure 23, TABLESAMPLE example
***********************************************************************
CREATE TABLE sales_record
(sales#
INTEGER
NOT NULL
GENERATED ALWAYS AS IDENTITY
(START
WITH 1
,INCREMENT BY 1
,NO MAXVALUE
,NO CYCLE)
,sale_ts
TIMESTAMP
NOT NULL
,num_items
SMALLINT
NOT NULL
,payment_type
CHAR(2)
NOT NULL
,sale_value
DECIMAL(12,2)
NOT NULL
,sales_tax
DECIMAL(12,2)
,employee#
INTEGER
NOT NULL
,CONSTRAINT sales1
CHECK(payment_type IN ('CS','CR'))
,CONSTRAINT sales2
CHECK(sale_value
> 0)
,CONSTRAINT sales3
CHECK(num_items
> 0)
,CONSTRAINT sales4
FOREIGN KEY(employee#)
REFERENCES staff(id)
ON DELETE RESTRICT
,PRIMARY KEY(sales#));
Figure 24, Sample table definition
***********************************************************************
CREATE TABLE default_values
(c1
CHAR
NOT NULL
,d1
DECIMAL
NOT NULL);
Figure 25, Table with default column lengths
***********************************************************************
LABELED DURATIONS
ITEM
WORKS WITH DATE/TIME
<------------------------>
FIXED
<--------------------->
SINGULAR
PLURAL
SIZE
DATE
TIME
TIMESTAMP
===========
============
=====
====
====
=========
YEAR
YEARS
N
Y
Y
MONTH
MONTHS
N
Y
Y
DAY
DAYS
Y
Y
Y
HOUR
HOURS
Y
Y
Y
MINUTE
MINUTES
Y
Y
Y
SECOND
SECONDS
Y
Y
Y
MICROSECOND
MICROSECONDS
Y
Y
Y
Figure 26, Labeled Durations and Date/Time Types
***********************************************************************
SELECT
sales_date
,sales_date
,sales_date
,sales_date
,sales_date
- 10
DAY
AS d1
+ -1
MONTH AS d2
+ 99
YEARS AS d3
+ 55
DAYS
- 22
MONTHS AS d4
,sales_date + (4+6) DAYS
AS d5
FROM
sales
WHERE
sales_person = 'GOUNOT'
AND
sales_date
= '1995-12-31'
Figure 27, Example, Labeled Duration usage
<=
<=
<=
<=
ANSWER
==========
1995-12-31
1995-12-21
1995-11-30
2094-12-31
<=
<=
1994-04-24
1996-01-10
***********************************************************************
ANSWER
==========
SELECT
sales_date
<= 1995-12-31
,sales_date +
2 MONTH AS d1
<= 1996-02-29
,sales_date +
3 MONTHS AS d2
<= 1996-03-31
,sales_date +
2 MONTH
+
1 MONTH AS d3
<= 1996-03-29
,sales_date + (2+1) MONTHS AS d4
<= 1996-03-31
FROM
sales
WHERE
sales_person = 'GOUNOT'
AND
sales_date
= '1995-12-31';
Figure 28, Adding Months - Varying Results
***********************************************************************
DURATION-TYPE FORMAT
NUMBER-REPRESENTS
============= ============= =====================
DATE
DECIMAL(8,0)
yyyymmdd
TIME
DECIMAL(6,0)
hhmmss
TIMESTAMP
DECIMAL(20,6) yyyymmddhhmmss.zzzzzz
Figure 29, Date/Time Durations
USE-WITH-D-TYPE
===============
TIMESTAMP, DATE
TIMESTAMP, TIME
TIMESTAMP
***********************************************************************
SELECT
empno
ANSWER
,hiredate
====================================
,birthdate
EMPNO HIREDATE
BIRTHDATE
,hiredate - birthdate
------ ---------- ---------- ------FROM
employee
000150 1972-02-12 1947-05-17 240826.
WHERE
workdept = 'D11'
000200 1966-03-03 1941-05-29 240905.
AND
lastname < 'L'
000210 1979-04-11 1953-02-23 260116.
ORDER BY empno;
Figure 30, Date Duration Generation
***********************************************************************
ANSWER
==========
SELECT
hiredate
<= 1972-02-12
,hiredate - 12345678.
<= 0733-03-26
,hiredate - 1234 years
56 months
78 days
<= 0733-03-26
FROM
employee
WHERE
empno = '000150';
Figure 31, Subtracting a Date Duration
***********************************************************************
SPECIAL REGISTER
===============================================
CURRENT CLIENT_ACCTNG
CURRENT CLIENT_APPLNAME
CURRENT CLIENT_USERID
CURRENT CLIENT_WRKSTNNAME
CURRENT DATE
CURRENT DBPARTITIONNUM
CURRENT DEFAULT TRANSFORM GROUP
CURRENT DEGREE
CURRENT EXPLAIN MODE
CURRENT EXPLAIN SNAPSHOT
CURRENT ISOLATION
CURRENT LOCK TIMEOUT
CURRENT MAINTAINED TABLE TYPES FOR OPTIMIZATION
CURRENT PACKAGE PATH
CURRENT PATH
CURRENT QUERY OPTIMIZATION
CURRENT REFRESH AGE
CURRENT SCHEMA
CURRENT SERVER
CURRENT TIME
CURRENT TIMESTAMP
CURRENT TIMEZONE
CURRENT USER
SESSION_USER
SYSTEM_USER
USER
Figure 32, DB2 Special Registers
UPDATE
======
no
no
no
no
no
no
yes
yes
yes
yes
yes
yes
yes
yes
yes
yes
yes
yes
no
no
no
no
no
yes
no
yes
DATA-TYPE
=============
VARCHAR(255)
VARCHAR(255)
VARCHAR(255)
VARCHAR(255)
DATE
INTEGER
VARCHAR(18)
CHAR(5)
VARCHAR(254)
CHAR(8)
CHAR(2)
INTEGER
VARCHAR(254)
VARCHAR(4096)
VARCHAR(254)
INTEGER
DECIMAL(20,6)
VARCHAR(128)
VARCHAR(18)
TIME
TIMESTAMP
DECIMAL(6,0)
VARCHAR(128)
VARCHAR(128)
VARCHAR(128)
VARCHAR(128)
***********************************************************************
SET CURRENT ISOLATION = RR;
SET CURRENT SCHEMA
= 'ABC';
SELECT
CURRENT TIME
AS cur_TIME
,CURRENT ISOLATION AS cur_ISO
,CURRENT SCHEMA
AS cur_ID
FROM
sysibm.sysdummy1;
Figure 33, Using Special Registers
ANSWER
=======================
CUR_TIME CUR_ISO CUR_ID
-------- ------- -----12:15:16 RR
ABC
***********************************************************************
CREATE DISTINCT TYPE JAP_YEN AS DECIMAL(15,2) WITH COMPARISONS;
DROP
DISTINCT TYPE JAP_YEN;
Figure 35, Create and drop distinct type
***********************************************************************
CREATE TABLE customer
(id
INTEGER
,fname
VARCHAR(00010)
,lname
VARCHAR(00015)
,date_of_birth
DATE
,citizenship
CHAR(03)
,usa_sales
DECIMAL(9,2)
,eur_sales
DECIMAL(9,2)
,sales_office#
SMALLINT
,last_updated
TIMESTAMP
NOT NULL
NOT NULL WITH DEFAULT ''
NOT NULL WITH DEFAULT ''
,PRIMARY KEY(id));
Figure 36, Sample table, without distinct types
***********************************************************************
SELECT
id
,usa_sales + eur_sales AS tot_sales
FROM
customer;
Figure 37, Silly query, but works
***********************************************************************
CREATE DISTINCT TYPE USA_DOLLARS AS DECIMAL(9,2) WITH COMPARISONS;
CREATE DISTINCT TYPE EUR_DOLLARS AS DECIMAL(9,2) WITH COMPARISONS;
Figure 38, Create Distinct Type examples
***********************************************************************
CREATE TABLE customer
(id
INTEGER
NOT NULL
,fname
VARCHAR(00010)
NOT NULL WITH DEFAULT ''
,lname
VARCHAR(00015)
NOT NULL WITH DEFAULT ''
,date_of_birth
DATE
,citizenship
CHAR(03)
,usa_sales
USA_DOLLARS
,eur_sales
EUR_DOLLARS
,sales_office#
SMALLINT
,last_updated
TIMESTAMP
,PRIMARY KEY(id));
Figure 39, Sample table, with distinct types
***********************************************************************
SELECT
id
,usa_sales + eur_sales AS tot_sales
FROM
customer;
Figure 40, Silly query, now fails
SELECT
id
,DECIMAL(usa_sales) +
DECIMAL(eur_sales) AS tot_sales
FROM
customer;
Figure 41, Silly query, works again
***********************************************************************
SELECT
deptno
,admrdept
,'ABC' AS abc
FROM
department
WHERE
deptname LIKE '%ING%'
ORDER BY 1;
Figure 44, Sample SELECT statement
ANSWER
===================
DEPTNO ADMRDEPT ABC
------ -------- --B01
A00
ABC
D11
D01
ABC
***********************************************************************
SELECT
*
ANSWER (part of)
FROM
department
================
WHERE
deptname LIKE '%ING%'
DEPTNO etc...
ORDER BY 1;
------ ------>>>
B01
PLANNING
D11
MANUFACTU
Figure 45, Use "*" to select all columns in table
***********************************************************************
SELECT
deptno
,department.*
FROM
department
WHERE
deptname LIKE '%ING%'
ORDER BY 1;
department.*
ANSWER (part of)
,department.*
================
FROM
department
DEPTNO etc...
WHERE
deptname LIKE '%NING%'
------ ------>>>
ORDER BY 1;
B01
PLANNING
Figure 47, Select all columns twice
***********************************************************************
SELECT
years
,name
,id
FROM
staff
FETCH FIRST 3 ROWS ONLY;
ANSWER
=====================
YEARS NAME
ID
------ --------- ---7 Sanders
10
8 Pernal
20
5 Marenghi
30
Figure 49, FETCH FIRST without ORDER BY, gets random rows
***********************************************************************
SELECT
years
,name
,id
FROM
staff
WHERE
years IS NOT NULL
ORDER BY years DESC
FETCH FIRST 3 ROWS ONLY;
Figure 50, FETCH FIRST with ORDER BY, gets wrong
ANSWER
=====================
YEARS NAME
ID
------ --------- ---13 Graham
310
12 Jones
260
10 Hanes
50
answer
***********************************************************************
SELECT
years
,name
,id
FROM
staff
WHERE
years IS NOT NULL
ORDER BY years DESC
,id
DESC
FETCH FIRST 3 ROWS ONLY;
Figure 51, FETCH FIRST with ORDER BY, gets right
ANSWER
=====================
YEARS NAME
ID
------ --------- ---13 Graham
310
12 Jones
260
10 Quill
290
answer
***********************************************************************
SELECT
a.empno
,a.lastname
FROM
employee a
,(SELECT MAX(empno)AS empno
FROM
employee) AS b
WHERE
a.empno = b.empno;
Figure 52, Correlation Name usage example
ANSWER
=================
EMPNO LASTNAME
------ ---------000340 GOUNOT
***********************************************************************
SELECT
a.empno
,a.lastname
,b.deptno AS dept
FROM
employee
a
,department b
WHERE
a.workdept = b.deptno
AND
a.job
<> 'SALESREP'
AND
b.deptname = 'OPERATIONS'
AND
a.sex
IN ('M','F')
AND
b.location IS NULL
ORDER BY 1;
Figure 53, Correlation name usage example
ANSWER
======================
EMPNO LASTNAME
DEPT
------ ---------- ---000090 HENDERSON E11
000280 SCHNEIDER E11
000290 PARKER
E11
000300 SMITH
E11
000310 SETRIGHT
E11
SELECT
ANSWER
===================
E_NUM
M INT ...
------ ----- ---000010 I
3978
000020 L
3476
empno
AS e_num
,midinit AS "m int"
,phoneno AS "..."
FROM
employee
WHERE
empno < '000030'
ORDER BY 1;
Figure 54, Renaming fields using AS
SELECT
FROM
WHERE
AVG(comm)
AS a1
,SUM(comm) / COUNT(*) AS a2
staff
id < 100;
SELECT
COUNT(*)
AS num
ANSWER
===================
E_NUM
M INT ...
------ ----- ---000010 I
3978
ANSWER
===============
A1
A2
------- -----796.025 530.68
ANSWER
FROM
WHERE
,MAX(lastname) AS max
employee
firstnme = 'FRED';
========
NUM MAX
--- --0 -
Figure 57, Getting a NULL value from a field defined NOT NULL
SELECT
AVG(comm)
AS a1
,SUM(comm) / COUNT(*) AS a2
FROM
staff
WHERE
id < 100
AND
comm IS NOT NULL;
Figure 58, AVG of those rows that are not null
SELECT
'JOHN'
,'JOHN''S'
,'''JOHN''S'''
,'"JOHN''S"'
FROM
staff
WHERE
id = 10;
Figure 59, Quote usage
SELECT
AS
AS
AS
AS
J1
J2
J3
J4
id
AS "USER ID"
,dept
AS "D#"
,years
AS "#Y"
,'ABC'
AS "'TXT'"
,'"'
AS """quote"" fld"
FROM
staff s
WHERE
id < 40
ORDER BY "USER ID";
Figure 60, Double-quote usage
ANSWER
===============
A1
A2
------- -----796.025 796.02
ANSWER
=============================
J1
J2
J3
J4
---- ------ -------- -------JOHN JOHN'S 'JOHN'S' "JOHN'S"
ANSWER
===============================
USER ID D# #Y 'TXT' "quote" fld
------- -- -- ----- ----------10 20 7 ABC
"
20 20 8 ABC
"
30 38 5 ABC
"
SELECT
FROM
WHERE
AND NOT
AND NOT
ANSWER
===============
ID
JOB
DEPT
--- ---- ---10 Mgr
20
AND
id
<> 100
AND
id
>=
0
AND
id
<= 150
AND NOT dept =
50
ORDER BY id;
Figure 62, Basic Predicate examples
30
50
140
Mgr
Mgr
Mgr
38
15
51
SELECT
id, dept, job
FROM
staff
WHERE
(id,dept) = (30,28)
OR
(id,years) = (90, 7)
OR
(dept,job) = (38,'Mgr')
ORDER BY 1;
Figure 64, Basic Predicate example, multi-value check
ANSWER
===========
ID DEPT JOB
-- ---- --30
38 Mgr
SELECT
id, dept, job
FROM
staff
WHERE
(id
= 30 AND dept
OR
(id
= 90 AND years
OR
(dept = 38 AND job
ORDER BY 1;
Figure 65, Same query as prior,
ANSWER
===========
ID DEPT JOB
-- ---- --30
38 Mgr
=
28)
=
7)
= 'Mgr')
using individual predicates
SELECT
id, job
ANSWER
FROM
staff
========
WHERE
job = ANY (SELECT job FROM staff)
ID JOB
AND
id <= ALL (SELECT id FROM staff)
--- ---ORDER BY id;
10 Mgr
Figure 67, Quantified Predicate example, two single-value sub-queries
SELECT
FROM
WHERE
ANSWER
=========
ID JOB
--- ----10 Mgr
20 Sales
30 Mgr
ANSWER
=========
ID JOB
--- ----10 Mgr
20 Sales
30 Mgr
40 Sales
SELECT
FROM
WHERE
AND
id, job
staff a
id IN (10,20,30)
id IN (SELECT id
FROM
staff)
AND id NOT IN 99
ORDER BY id;
Figure 74, IN Predicate examples, single values
ANSWER
=========
ID JOB
--- ----10 Mgr
20 Sales
30 Mgr
SELECT
FROM
WHERE
ANSWER
===============
EMPNO LASTNAME
------ ------000260 JOHNSON
000270 PEREZ
empno, lastname
employee
(empno, 'AD3113') IN
(SELECT empno, projno
FROM
emp_act
WHERE emptime > 0.5)
ORDER BY 1;
Figure 75, IN Predicate example, multi-value
ANSWER
==============
ID
NAME
--- --------130 Yamaguchi
200 Scoutten
LIKE 'AB+%++%'
ESCAPE '+'
Figure 78, LIKE and ESCAPE examples
SELECT
FROM
WHERE
AND
AND
AND
AND
Figure
id
staff
id = 10
'ABC' LIKE 'AB%'
'A%C' LIKE 'A/%C' ESCAPE '/'
'A_C' LIKE 'A\_C' ESCAPE '\'
'A_$' LIKE 'A$_$$' ESCAPE '$';
79, LIKE and ESCAPE examples
ANSWER
======
ID
--10
SELECT
id, comm
FROM
staff
WHERE
id
< 100
AND
id
IS NOT NULL
AND
comm IS
NULL
AND NOT comm IS NOT NULL
ORDER BY id;
Figure 81, NULL predicate examples
ANSWER
=========
ID
COMM
--- ---10 30 50 -
SELECT
id
,name
FROM
staff
WHERE
name LIKE '%a' || X'3B' || '%'
ORDER BY id;
Figure 82, Refer to semi-colon in SQL text
Example:
555 +
-22
(12 - 3) * 66
^
^
^
^
5th 2nd 3rd
1st
Figure 83, Precedence rules example
^
4th
ANSWER
======
423
SELECT
FROM
(12
,
-22 / (12
,
-22 / (12
,555 + -22 / (12
sysibm.sysdummy1;
3)
3)
3) * 66
3) * 66
AS
AS
AS
AS
int1
int2
int3
int4
ANSWER
===================
INT1 INT2 INT3 INT4
---- ---- ---- ---9
-2 -132 423
SELECT
FROM
(12.0
,
-22 / (12.0
,
-22 / (12.0
,555 + -22 / (12.0
sysibm.sysdummy1;
3)
3)
3) * 66
3) * 66
AS
AS
AS
AS
dec1
dec2
dec3
dec4
ANSWER
===========================
DEC1
DEC2
DEC3
DEC4
------ ------ ------ -----9.0
-2.4 -161.3 393.6
Figure 85, Precedence rules, decimal example
SELECT
FROM
WHERE
AND
OR
ORDER BY
*
table1
col1 = 'C'
col1 >= 'A'
col2 >= 'AA'
col1;
ANSWER>>
COL1 COL2
---- ---A
AA
B
BB
C
CC
SELECT
*
FROM
table1
WHERE
(col1 = 'C'
AND
col1 >= 'A')
OR
col2 >= 'AA'
ORDER BY col1;
ANSWER>>
COL1
---A
B
C
SELECT
*
ANSWER>>
FROM
table1
WHERE
col1 = 'C'
AND
(col1 >= 'A'
OR
col2 >= 'AA')
ORDER BY col1;
Figure 86, Use of OR and parenthesis
COL2
---AA
BB
CC
COL1 COL2
---- ---C
CC
TABLE1
+---------+
|COL1|COL2|
|----|----|
|A
|AA |
|B
|BB |
|C
|CC |
+---------+
SELECT
id
,salary
,CAST(salary AS INTEGER) AS sal2
FROM
staff
WHERE
id < 30
ORDER BY id;
Figure 88, Use CAST expression to convert Decimal to
ANSWER
=================
ID SALARY
SAL2
-- -------- ----10 18357.50 18357
20 18171.25 18171
Integer
SELECT
ANSWER
=============
ID JOB
JOB2
-- ----- ---10 Mgr
Mgr
20 Sales Sal
id
,job
,CAST(job AS CHAR(3)) AS job2
FROM
staff
WHERE
id < 30
ORDER BY id;
Figure 89, Use CAST expression to truncate Char field
SELECT
id
,CAST(NULL AS SMALLINT) AS junk
FROM
staff
WHERE
id < 30
ORDER BY id;
ANSWER
=======
ID JUNK
-- ---10
20
Figure 90, Use CAST expression to define SMALLINT field with null values
SELECT
stf.id
,emp.empno
FROM
staff
stf
LEFT OUTER JOIN
employee emp
ON
stf.id
= CAST(emp.empno AS SMALLINT)
AND
emp.job = 'MANAGER'
WHERE
stf.id
< 60
ORDER BY stf.id;
Figure 91, CAST expression in join
ANSWER
=========
ID EMPNO
-- -----10 20 000020
30 000030
40 50 000050
SELECT
ANSWER
=========
stf.id
,emp.empno
FROM
staff
stf
LEFT OUTER JOIN
employee emp
ON
stf.id
= SMALLINT(emp.empno)
AND
emp.job = 'MANAGER'
WHERE
stf.id
< 60
ORDER BY stf.id;
Figure 92, Function usage in join
ID
-10
20
30
40
50
EMPNO
-----000020
000030
000050
VALUES
6
VALUES (6)
VALUES
6, 7, 8
VALUES (6), (7), (8)
VALUES (6,66), (7,77), (8,NULL)
Figure 94, VALUES usage examples
<=
<=
<=
<=
<=
1
1
1
3
3
row,
row,
row,
rows,
rows,
1
1
3
1
2
column
column
columns
column
columns
ANSWER
=========
COL1 COL2
---- ---0 AA
1 BB
2 -
ANSWER
=========
COL1 COL2
---- ---0.0 AA
1.0 BB
2.0 -
ANSWER
=========
,(
,(
1, CAST('BB' AS CHAR(1)))
2, CAST(NULL AS CHAR(1)))
)
SELECT *
FROM
temp1;
Figure 97, Use VALUES to define a temporary table (3 of 4)
COL1
---0
1
2
COL2
---A
B
-
ANSWER
=========
COL1 COL2
---- ---0 A
1 B
2 -
ANSWER
==========
COL1B COLX
----- ---0 0.00
1 2.11
2 4.22
ANSWER
======
COL1
---0
1
)
2
SELECT *
3
FROM
temp1;
etc
Figure 101, Use VALUES defined data to seed a recursive SQL statement
SELECT
FROM
*
(VALUES (123,'ABC')
,(234,'DEF')
)AS ttt
ORDER BY 1 DESC;
Figure 102, Generate table with unnamed columns
ANSWER
======
--- --234 DEF
123 ABC
SELECT
Lastname
,sex
AS sx
,CASE sex
WHEN 'F' THEN 'FEMALE'
WHEN 'M' THEN 'MALE'
ELSE NULL
END AS sexx
FROM
employee
WHERE
lastname LIKE 'J%'
ORDER BY 1;
Figure 104, Use CASE (1st type) to expand a value
ANSWER
====================
LASTNAME
SX SEXX
---------- -- -----JEFFERSON M MALE
JOHNSON
F FEMALE
JONES
M MALE
SELECT
lastname
,sex
AS sx
,CASE
WHEN sex = 'F' THEN 'FEMALE'
WHEN sex = 'M' THEN 'MALE'
ELSE NULL
END AS sexx
FROM
employee
WHERE
lastname LIKE 'J%'
ORDER BY 1;
ANSWER
====================
LASTNAME
SX SEXX
---------- -- -----JEFFERSON M MALE
JOHNSON
F FEMALE
JONES
M MALE
SELECT
lastname
ANSWER
,midinit AS mi
===================
,sex
AS sx
LASTNAME
MI SX MX
,CASE
---------- -- -- -WHEN midinit > SEX
JEFFERSON J M M
THEN midinit
JOHNSON
P F P
ELSE sex
JONES
T M T
END AS mx
FROM
employee
WHERE
lastname LIKE 'J%'
ORDER BY 1;
Figure 107, Use CASE to display the higher of two values
SELECT
COUNT(*)
,SUM(CASE sex WHEN 'F' THEN 1 ELSE 0 END)
,SUM(CASE sex WHEN 'M' THEN 1 ELSE 0 END)
FROM
employee
WHERE
lastname LIKE 'J%';
Figure 108, Use CASE to get multiple counts in one
SELECT
lastname
,LENGTH(RTRIM(lastname)) AS len
,SUBSTR(lastname,1,
CASE
WHEN LENGTH(RTRIM(lastname))
> 6 THEN 6
ELSE LENGTH(RTRIM(lastname))
END ) AS lastnm
FROM
employee
WHERE
lastname LIKE 'J%'
ORDER BY 1;
Figure 109, Use CASE inside a function
UPDATE staff
SET
comm = CASE dept
WHEN 15 THEN comm *
WHEN 20 THEN comm *
WHEN 38 THEN
CASE
WHEN years <
WHEN years >=
AS tot
AS #f
AS #m
ANSWER
=========
TOT #F #M
--- -- -3 1 2
pass
ANSWER
=====================
LASTNAME
LEN LASTNM
---------- --- -----JEFFERSON
9 JEFFER
JOHNSON
7 JOHNSO
JONES
5 JONES
1.1
1.2
5 THEN comm * 1.3
5 THEN comm * 1.4
ELSE NULL
END
ELSE comm
END
WHERE comm IS NOT NULL
AND dept < 50;
Figure 110, UPDATE statement with nested CASE expressions
ANSWER
========
C1 C2 C3
-- -- -88 9 9
44 3 14
22 0 0 1 0
SELECT
lastname
,sex
,CASE
WHEN sex >= 'M' THEN 'MAL'
WHEN sex >= 'F' THEN 'FEM'
END AS sxx
FROM
employee
WHERE
lastname LIKE 'J%'
ORDER BY 1;
Figure 112, Use CASE to derive a value (correct)
ANSWER
=================
LASTNAME
SX SXX
---------- -- --JEFFERSON M MAL
JOHNSON
F FEM
JONES
M MAL
SELECT
ANSWER
=================
LASTNAME
SX SXX
---------- -- --JEFFERSON M FEM
JOHNSON
F FEM
JONES
M FEM
lastname
,sex
,CASE
WHEN sex >= 'F' THEN 'FEM'
WHEN sex >= 'M' THEN 'MAL'
END AS sxx
FROM
employee
WHERE
lastname LIKE 'J%'
ORDER BY 1;
Figure 113, Use CASE to derive a value (incorrect)
SELECT
id
,dept
ANSWER
=======================
,salary
,comm
FROM
staff
WHERE
CASE
WHEN comm
<
70
WHEN name
LIKE 'W%'
WHEN salary
< 11000
WHEN salary
< 18500
AND dept
<>
33
WHEN salary
< 19000
END IN ('A','C','E')
ORDER BY id;
Figure 114, Use CASE in a predicate
SELECT
FROM
WHERE
OR
OR
id
,name
,salary
,comm
staff
(comm
< 70)
(salary < 11000
(salary < 19000
THEN 'A'
THEN 'B'
THEN 'C'
ID DEPT SALARY
COMM
--- ---- -------- ----130
42 10505.90 75.60
270
66 18555.50
330
66 10988.00 55.50
THEN 'D'
THEN 'E'
ANSWER
=======================
ID DEPT SALARY
COMM
--- ---- -------- ----130
42 10505.90 75.60
270
66 18555.50
330
66 10988.00 55.50
AND NOT name LIKE 'W%')
AND NOT (name LIKE 'W%'
OR (salary < 18500 AND dept <> 33)))
ORDER BY id;
Figure 115, Same stmt as prior, without CASE predicate
fred
:name-var
,:salary-var
SELECT
name
,salary
INTO
:name-var
,:salary-var
FROM
staff
WHERE
id = :id-var
Figure 119, Singleton select
SET
(:hv1
,:hv2
,:hv3) =
(SELECT id
,name
,salary
FROM
staff
WHERE
id = :id-var)
Figure 124, SET using row-fullselect
SET CONNECTION
SET CURRENT DEFAULT TRANSFORM GROUP
SET CURRENT DEGREE
SET CURRENT EXPLAIN MODE
SET CURRENT EXPLAIN SNAPSHOT
SET CURRENT ISOLATION
SET CURRENT LOCK TIMEOUT
SET CURRENT MAINTAINED TABLE TYPES FOR OPTIMIZATION
SET CURRENT PACKAGE PATH
SET CURRENT PACKAGESET
SET CURRENT QUERY OPTIMIZATION
SET CURRENT REFRESH AGE
SET ENCRYPTION PASSWORD
SET EVENT MONITOR STATE
SET INTEGRITY
SET PASSTHRU
SET PATH
SET SCHEMA
SET SERVER OPTION
SET SESSION AUTHORIZATION
Figure 125, Other SET statements
NOT NULL
NOT NULL
NOT NULL
INSERT INTO
(SELECT *
FROM
emp_act
WHERE empno < '1'
)
VALUES ('510000' ,'ABC' ,10 ,1.4 ,'2003-10-22', '2003-11-24');
Figure 136, Insert into a full-select
INSERT
SELECT
FROM
Figure
INTO emp_act
*
emp_act;
139, Stupid - insert - doubles rows
INSERT INTO
(SELECT
*
FROM
us_customer
UNION ALL
SELECT
*
FROM
intl_customer)
VALUES (111,'Fred','USA')
,(222,'Dave','USA')
,(333,'Juan','MEX');
Figure 144, Insert into multiple tables
UPDATE
SET
emp_act
emptime = NULL
,emendate = DEFAULT
,emstdate = CURRENT DATE + 2 DAYS
,actno
= ACTNO / 2
,projno
= 'ABC'
WHERE
empno
= '100000';
Figure 145, Single row update
UPDATE emp_act
SET
actno = actno / 2;
Figure 147, Mass update
UPDATE
SET
emp_act ac1
actno
= actno * 2
,emptime
= actno * 2
WHERE
empno LIKE '910%';
Figure 148, Two columns get same value
UPDATE
SET
emp_act
actno
= (SELECT MAX(salary)
FROM
staff)
WHERE
empno
= '200000';
Figure 149, Update using select
UPDATE emp_act
SET
(actno
,emstdate
,projno) = (SELECT MAX(salary)
,CURRENT DATE + 2 DAYS
,MIN(CHAR(id))
FROM
staff
WHERE id <> 33)
WHERE
empno LIKE '600%';
Figure 150, Multi-row update using select
UPDATE emp_act
SET
emptime = 10
WHERE
empno
= '000010'
AND
projno = 'MA2100';
Figure 152, Direct update of table
UPDATE
(SELECT *
FROM
emp_act
WHERE
empno
= '000010'
AND
projno = 'MA2100'
)AS ea
SET emptime = 20;
Figure 153, Update of full-select
UPDATE
SET
emp_act ea1
emptime = (SELECT MAX(emptime)
FROM
emp_act ea2
WHERE ea1.empno = ea2.empno)
WHERE
empno
= '000010'
AND
projno = 'MA2100';
Figure 154, Set employee-time in row to MAX - for given employee
UPDATE
(SELECT
ea1.*
,MAX(emptime) OVER(PARTITION BY empno) AS maxtime
emp_act ea1
FROM
)AS ea2
SET
emptime
WHERE
empno
AND
projno
Figure 155, Use
= maxtime
= '000010'
= 'MA2100';
OLAP function to get max-time, then apply (correct)
UPDATE emp_act
SET
emptime
WHERE
empno
AND
projno
Figure 156, Use
DELETE
FROM
emp_act
WHERE
empno
= '000010'
AND
projno
= 'MA2100'
AND
actno
= 10;
Figure 159, Single-row delete
DELETE
FROM
emp_act;
Figure 161, Mass delete
DELETE
FROM
emp_act
WHERE
empno
LIKE '00%'
AND
projno
>= 'MA';
Figure 162, Selective delete
DELETE
FROM
WHERE
staff s1
id NOT IN
(SELECT MAX(id)
FROM
staff s2
WHERE s1.dept = s2.dept);
Figure 163, Correlated delete (1 of 2)
DELETE
FROM
WHERE
staff s1
EXISTS
(SELECT *
FROM
staff s2
WHERE s2.dept = s1.dept
AND s2.id
> s1.id);
Figure 164, Correlated delete (2 of 2)
DELETE FROM
(SELECT id
,MAX(id) OVER(PARTITION BY dept) AS max_id
FROM
staff
)AS ss
WHERE id <> max_id;
Figure 165, Delete using full-select and OLAP function
DELETE
FROM
emp_act
WHERE (empno, projno, actno) IN
(SELECT empno
,projno
,actno
FROM
(SELECT eee.*
,ROW_NUMBER()
OVER(ORDER BY empno, projno, actno) AS r#
FROM
emp_act eee
)AS xxx
WHERE
r# <= 10);
Figure 166, Delete first "n" rows
SELECT
ANSWER
==============
EMPNO PRJ ACT
------ --- --200000 ABC 10
200000 DEF 10
empno
,projno AS prj
,actno AS act
FROM
FINAL TABLE
(INSERT INTO emp_act
VALUES ('200000','ABC',10 ,1,'2003-10-22','2003-11-24')
,('200000','DEF',10 ,1,'2003-10-22','2003-11-24'))
ORDER BY 1,2,3;
Figure 168, Select rows inserted
SELECT
empno
,projno AS prj
,actno AS act
,row#
AS r#
FROM
FINAL TABLE
(INSERT INTO emp_act (empno, projno, actno)
INCLUDE (row# SMALLINT)
VALUES ('300000','ZZZ',999,1)
,('300000','VVV',111,2))
ORDER BY row#;
Figure 169, Include column to get insert sequence
ANSWER
=================
EMPNO PRJ ACT R#
------ --- --- -300000 ZZZ 999 1
300000 VVV 111 2
SELECT
empno
,projno AS prj
,actno AS act
,ROW_NUMBER() OVER() AS r#
FROM
FINAL TABLE
(INSERT INTO emp_act (empno, projno, actno)
VALUES ('400000','ZZZ',999)
,('400000','VVV',111))
ORDER BY INPUT SEQUENCE;
Figure 170, Select rows in insert order
ANSWER
=================
EMPNO PRJ ACT R#
------ --- --- -400000 ZZZ 999 1
400000 VVV 111 2
SELECT
ANSWER
=================
EMPNO PRJ ACT R#
------ --- -- -600010 1
59 1
600020 563 59 2
600030 193 59 3
empno
,projno AS prj
,actno AS act
,ROW_NUMBER() OVER() AS r#
FROM
NEW TABLE
(INSERT INTO emp_act (empno, actno, projno)
SELECT LTRIM(CHAR(id + 600000))
,SECOND(CURRENT TIME)
,CHAR(SMALLINT(RAND(1) * 1000))
FROM
staff
WHERE
id < 40)
ORDER BY INPUT SEQUENCE;
Figure 171, Select from an insert that has unknown values
SELECT
empno
,projno AS prj
,emptime AS etime
FROM
OLD TABLE
(UPDATE emp_act
SET
emptime = emptime * 2
WHERE empno
= '200000')
ORDER BY projno;
Figure 172, Select values - from before update
ANSWER
================
EMPNO PRJ ETIME
------ --- ----200000 ABC 1.00
200000 DEF 1.00
SELECT
ANSWER
===============
PRJ OLD_T NEW_T
--- ----- ----ABC 2.00 0.02
DEF 2.00 11.27
SELECT
ANSWER
=======
PRJ ACT
--- --VVV 111
ZZZ 999
SELECT
ANSWER
====================
EMPNO PROJNO ACT R#
------ ------ --- -000260 AD3113 70 2
000260 AD3113 80 4
000260 AD3113 180 6
projno AS prj
,old_t
AS old_t
,emptime AS new_t
FROM
NEW TABLE
(UPDATE emp_act
INCLUDE (old_t DECIMAL(5,2))
SET
emptime = emptime * RAND(1) * 10
,old_t
= emptime
WHERE
empno
= '200000')
ORDER BY 1;
Figure 173, Select values - before and after update
projno AS prj
,actno AS act
FROM
OLD TABLE
(DELETE
FROM
emp_act
WHERE empno = '300000')
ORDER BY 1,2;
Figure 174, List deleted rows
empno
,projno
,actno AS act
,row#
AS r#
FROM
OLD TABLE
(DELETE
FROM
emp_act
SELECT
empno
,(SELECT lastname
FROM
(SELECT empno AS e#
,lastname
FROM
employee
)AS xxx
WHERE
empno = e#)
,projno AS projno
,actno AS act
FROM
OLD TABLE
(DELETE
FROM
emp_act
WHERE
empno < '0001')
FETCH FIRST 5 ROWS ONLY;
Figure 176, Join result to another table
ANSWER
==========================
EMPNO LASTNAME PROJNO ACT
------ -------- ------ --000010 HAAS
AD3100 10
000010 HAAS
MA2100 10
000010 HAAS
MA2110 10
000020 THOMPSON PL2100 30
000030 KWAN
IF1000 10
INTO old_staff
id, job, salary
staff
id BETWEEN 20 and 40;
178, Sample tables for merge
OLD_STAFF
+-----------------+
|ID|JOB |SALARY |
|--|-----|--------|
|20|Sales|18171.25|
|30|Mgr |17506.75|
|40|Sales|18006.00|
+-----------------+
INSERT
SELECT
FROM
WHERE
NEW_STAFF
+----------+
|ID|SALARY |
|--|-------|
|30|1750.67|
|40|1800.60|
|50|2065.98|
+----------+
INTO new_staff
id, salary / 10
staff
id BETWEEN 30 and 50;
OLD_STAFF
+-----------------+
NEW_STAFF
+----------+
ON
oo.id = nn.id
WHEN MATCHED THEN
UPDATE
SET oo.salary = nn.salary
WHEN NOT MATCHED THEN
INSERT
VALUES (nn.id,'?',nn.salary);
|ID|JOB |SALARY |
|--|-----|--------|
|20|Sales|18171.25|
|30|Mgr |17506.75|
|40|Sales|18006.00|
+-----------------+
|ID|SALARY |
|--|-------|
|30|1750.67|
|40|1800.60|
|50|2065.98|
+----------+
AFTER-MERGE
=================
ID JOB
SALARY
-- ----- -------20 Sales 18171.25
30 Mgr
1750.67
40 Sales 1800.60
50 ?
2065.98
AFTER-MERGE
=================
ID JOB
SALARY
-- ----- -------20 Sales 18171.25
AFTER-MERGE
=================
ID JOB
SALARY
-- ----- -------20 Sales 18171.25
FROM
old_staff
)AS mx
ON
id = max_id
WHEN NOT MATCHED THEN
INSERT
VALUES (max_id, max_job, max_sal);
Figure 182, Merge MAX row into table
30 Mgr
17506.75
40 Sales 18006.00
41 Sales 18171.25
MERGE INTO
OLD_STAFF
NEW_STAFF
(SELECT *
+-----------------+ +----------+
FROM
old_staff
|ID|JOB |SALARY | |ID|SALARY |
WHERE id < 40
|--|-----|--------| |--|-------|
)AS oo
|20|Sales|18171.25| |30|1750.67|
USING
|30|Mgr |17506.75| |40|1800.60|
(SELECT *
|40|Sales|18006.00| |50|2065.98|
FROM
new_staff
+-----------------+ +----------+
WHERE id < 50
)AS nn
AFTER-MERGE
ON
oo.id = nn.id
=================
WHEN MATCHED THEN
ID JOB
SALARY
DELETE
-- ----- -------WHEN NOT MATCHED THEN
20 Sales 18171.25
INSERT
40 ?
1800.60
VALUES (nn.id,'?',nn.salary);
40 Sales 18006.00
Figure 184, Merge using two full-selects
AFTER-MERGE
=================
ID JOB
SALARY
-- ----- -------20 Sales 18171.25
30 ?
1234.00
40 ?
1234.00
50 ?
5678.90
BEGIN ATOMIC
DECLARE cntr SMALLINT DEFAULT 1;
FOR V1 AS
SELECT
id as idval
FROM
staff
WHERE
id < 80
ORDER BY id
DO
UPDATE
staff
SET
comm = cntr
WHERE
id
= idval;
SET cntr = cntr + 1;
END FOR;
END
Figure 187, Sample Compound SQL statement
--#SET DELIMITER !
SELECT NAME FROM STAFF WHERE ID = 10!
--#SET DELIMITER ;
SELECT NAME FROM STAFF WHERE ID = 20;
Figure 188, Set Delimiter example
BEGIN ATOMIC
DECLARE aaa, bbb, ccc SMALLINT DEFAULT 1;
DECLARE ddd
CHAR(10) DEFAULT NULL;
DECLARE eee
INTEGER;
SET eee = aaa + 1;
UPDATE
staff
SET
comm
= aaa
,salary = bbb
,years = eee
WHERE
id
= 10;
END
Figure 189, DECLARE examples
BEGIN ATOMIC
FOR V1 AS
SELECT
DO
dept
AS dname
,max(id) AS max_id
FROM
staff
GROUP BY dept
HAVING
COUNT(*) > 1
ORDER BY dept
UPDATE
SET
WHERE
UPDATE
set
WHERE
AND
END FOR;
staff
id
=
id
=
staff
dept =
dept =
dept <
id * -1
max_id;
dept / 10
dname
30;
END
Figure 191, FOR statement example
BEGIN ATOMIC
DECLARE numrows INT DEFAULT 0;
UPDATE staff
SET
salary = 12345
WHERE ID < 100;
GET DIAGNOSTICS numrows = ROW_COUNT;
UPDATE staff
SET
salary = numrows
WHERE ID = 10;
END
Figure 193, GET DIAGNOSTICS statement example
BEGIN ATOMIC
DECLARE cur INT;
BEGIN ATOMIC
DECLARE cntr INT DEFAULT 0;
whileloop:
WHILE cntr < 60 DO
SET cntr = cntr + 10;
UPDATE staff
SET
salary = cntr
WHERE id
= cntr;
ITERATE whileloop;
UPDATE staff
SET
comm
= cntr + 1
WHERE id
= cntr;
END WHILE;
END
Figure 197, ITERATE statement example
BEGIN ATOMIC
DECLARE cntr INT DEFAULT 1;
whileloop:
WHILE 1 <> 2 DO
SET cntr = cntr + 1;
IF RAND() > 0.99 THEN
LEAVE whileloop;
END IF;
END WHILE;
UPDATE staff
SET
salary = cntr
WHERE ID = 10;
END
Figure 199, LEAVE statement example
BEGIN ATOMIC
DECLARE cntr INT DEFAULT 1;
DECLARE emsg CHAR(20);
whileloop:
WHILE RAND() < .99 DO
SET cntr = cntr + 1;
END WHILE;
SET emsg = '#loops: ' || CHAR(cntr);
SIGNAL SQLSTATE '75001' SET MESSAGE_TEXT = emsg;
END
Figure 201, SIGNAL statement example
BEGIN ATOMIC
DECLARE c1, C2 INT DEFAULT 1;
WHILE c1 < 10 DO
WHILE c2 < 20 DO
SET c2 = c2 + 1;
END WHILE;
SET c1 = c1 + 1;
END WHILE;
UPDATE staff
SET
salary = c1
,comm
= c2
WHERE id
= 10;
END
Figure 203, WHILE statement example
SELECT
dept
,count(*) as #rows
FROM
staff
GROUP BY dept
ORDER BY dept;
ANSWER
==========
DEPT #ROWS
---- ----10
4
15
4
20
4
38
5
42
4
51
5
66
5
84
4
--#SET DELIMITER !
CREATE TABLE dpt
(dept
SMALLINT
,#names SMALLINT
,PRIMARY KEY(dept))!
COMMIT!
NOT NULL
IMPORTANT
============
This example
uses an "!"
as the stmt
delimiter.
ANSWER
===========
DEPT #NAMES
---- -----10
4
15
4
20
4
38
5
42
4
51
5
66
5
84
4
--#SET DELIMITER !
CREATE FUNCTION dpt1 (deptin SMALLINT)
RETURNS SMALLINT
BEGIN ATOMIC
DECLARE num_names SMALLINT;
FOR getnames AS
SELECT
COUNT(*) AS #n
FROM
staff
WHERE
dept = deptin
DO
SET num_names = #n;
END FOR;
RETURN num_names;
END!
COMMIT!
SELECT
XXX.*
,dpt1(dept) as #names
FROM
(SELECT
dept
FROM
staff
GROUP BY dept
)AS XXX
ORDER BY dept!
Figure 206, Scalar Function with compound SQL
--#SET DELIMITER !
CREATE FUNCTION dpt1 (deptin SMALLINT)
RETURNS SMALLINT
BEGIN ATOMIC
RETURN
SELECT COUNT(*)
FROM
staff
WHERE dept = deptin;
END!
COMMIT!
IMPORTANT
============
This example
uses an "!"
as the stmt
delimiter.
ANSWER
===========
DEPT #NAMES
---- -----10
4
15
4
20
4
38
5
42
4
51
5
66
5
84
4
IMPORTANT
============
This example
uses an "!"
as the stmt
delimiter.
SELECT
XXX.*
,dpt1(dept) as #names
FROM
(SELECT
dept
FROM
staff
GROUP BY dept
)AS XXX
ORDER BY dept!
Figure 207, Scalar Function with compound SQL
--#SET DELIMITER !
CREATE FUNCTION dpt2 ()
RETURNS TABLE (dept
SMALLINT
,#names SMALLINT)
BEGIN ATOMIC
IMPORTANT
============
This example
uses an "!"
as the stmt
delimiter.
RETURN
SELECT
dept
,count(*)
FROM
staff
GROUP BY dept
ORDER BY dept;
END!
COMMIT!
--#SET DELIMITER ;
SELECT
*
FROM
TABLE(dpt2()) T1
ORDER BY dept;
Figure 208, Table Function with compound SQL
ANSWER
===========
DEPT #NAMES
---- -----10
4
15
4
20
4
38
5
42
4
51
5
66
5
84
4
SELECT
AVG(dept)
AS a1
,AVG(ALL dept)
AS a2
,AVG(DISTINCT dept) AS a3
,AVG(dept/10)
AS a4
,AVG(dept)/10
AS a5
FROM
staff
HAVING
AVG(dept) > 40;
Figure 210, AVG function examples
ANSWER
==============
A1 A2 A3 A4 A5
-- -- -- -- -41 41 40 3 4
UPDATE staff
SET
comm = 0
WHERE comm IS NULL;
SELECT AVG(salary) AS salary
,AVG(comm)
AS comm1
,AVG(CASE comm
WHEN 0 THEN NULL
ELSE comm
END) AS comm2
FROM
staff;
UPDATE
SET
WHERE
Figure
staff
comm = NULL
comm = 0;
211, Convert zero to null before doing AVG
ANSWER
===================
SALARY COMM1 COMM2
------- ----- ----16675.6 351.9 513.3
SELECT
COUNT(*) AS c1
,AVG(salary) AS a1
,COALESCE(AVG(salary),0) AS a2
,CASE
WHEN AVG(salary) IS NULL THEN 0
ELSE AVG(salary)
END AS a3
FROM
staff
WHERE
id < 10;
Figure 212, Convert null output (from AVG) to zero
SELECT
FROM
AVG(DAYS(birthdate))
,DATE(AVG(DAYS(birthdate)))
employee;
ANSWER
===========
C1 A1 A2 A3
-- -- -- -0 - 0 0
ANSWER
=================
1
2
------ ---------709113 1942-06-27
ANSWER
================
ANSWER
===========================
COR11 COR12 COR23 COR34
------ ------ ------ -----1.000 -1.000 -0.017 -0.005
AS
AS
AS
AS
cor11
cor12
cor23
cor34
FROM
temp1;
Figure 216, CORRELATION function examples
SELECT COUNT(*)
,COUNT(INT(comm/10))
,COUNT(ALL INT(comm/10))
,COUNT(DISTINCT INT(comm/10))
,COUNT(DISTINCT INT(comm))
,COUNT(DISTINCT INT(comm))/10
FROM
staff;
Figure 218, COUNT function examples
SELECT
FROM
WHERE
UNION
SELECT
'NO GP-BY'
,COUNT(*)
staff
id = -1
AS
AS
AS
AS
AS
AS
c1
c2
c3
c4
c5
c6
ANSWER
=================
C1 C2 C3 C4 C5 C6
-- -- -- -- -- -35 24 24 19 24 2
AS c1
AS c2
ANSWER
============
C1
C2
-------- -NO GP-BY
0
'GROUP-BY' AS c1
,COUNT(*)
AS c2
FROM
staff
WHERE
id = -1
GROUP BY dept;
Figure 219, COUNT function with and without GROUP BY
SELECT
COUNT_BIG(*)
AS
,COUNT_BIG(dept)
AS
,COUNT_BIG(DISTINCT dept)
AS
,COUNT_BIG(DISTINCT dept/10) AS
,COUNT_BIG(DISTINCT dept)/10 AS
FROM
STAFF;
Figure 221, COUNT_BIG function examples
c1
c2
c3
c4
c5
ANSWER
===================
C1 C2 C3 C4 C5
--- --- --- --- --35. 35. 8. 7. 0.
SELECT
dept
,AVG(salary)
AS salary
,GROUPING(dept) AS df
FROM
staff
GROUP BY ROLLUP(dept)
ORDER BY dept;
ANSWER
================
DEPT SALARY
DF
---- -------- -10 20865.86 0
15 15482.33 0
20 16071.52 0
38 15457.11 0
42 14592.26 0
51 17218.16 0
66 17215.24 0
84 16536.75 0
- 16675.64 1
SELECT
MAX(dept)
,MAX(ALL dept)
,MAX(DISTINCT dept)
,MAX(DISTINCT dept/10)
FROM
staff;
Figure 227, MAX function examples
SELECT MAX(hiredate)
,CHAR(MAX(hiredate),USA)
,MAX(CHAR(hiredate,USA))
FROM
employee;
ANSWER
===============
1
2
3
4
--- --- --- --84 84 84
8
ANSWER
================================
1
2
3
---------- ---------- ---------1980-09-30 09/30/1980 12/15/1976
SELECT MAX(id)
AS id
,MAX(CHAR(id))
AS chr
,MAX(DIGITS(id)) AS dig
FROM
staff;
ANSWER
===================
ID
CHR
DIG
------ ------ ----350 90
00350
ANSWER
=====================
ID
CHR DIG
----- ---- ---------100 90
0000000240
SELECT
FROM
MIN(dept)
,MIN(ALL dept)
,MIN(DISTINCT dept)
,MIN(DISTINCT dept/10)
staff;
ANSWER
===============
1
2
3
4
--- --- --- --10 10 10
1
SELECT
DEC(REGR_SLOPE(bonus,salary)
,7,5)
,DEC(REGR_INTERCEPT(bonus,salary),7,3)
,INT(REGR_COUNT(bonus,salary)
)
,INT(REGR_AVGX(bonus,salary)
)
,INT(REGR_AVGY(bonus,salary)
)
,INT(REGR_SXX(bonus,salary)
)
,INT(REGR_SXY(bonus,salary)
)
,INT(REGR_SYY(bonus,salary)
)
FROM
employee
WHERE
workdept = 'A00';
Figure 234, REGRESSION functions examples
AS
AS
AS
AS
AS
AS
AS
AS
r_slope
r_icpt
r_count
r_avgx
r_avgy
r_sxx
r_sxy
r_syy
ANSWERS
==========
0.01710
100.871
3
42833
833
296291666
5066666
86666
ANSWER
===============================
A1 S1
S2
S3
S4
-- ------------- ---- ---- ---41 +2.3522355E+1 23.5 23.5 24.1
SELECT AVG(dept) AS a1
,STDDEV(dept) AS s1
,DEC(STDDEV(dept),3,1) AS s2
,DEC(STDDEV(ALL dept),3,1) AS s3
,DEC(STDDEV(DISTINCT dept),3,1) AS s4
FROM
staff;
Figure 236, STDDEV function examples
SELECT
SUM(dept)
AS s1
,SUM(ALL dept)
AS s2
,SUM(DISTINCT dept) AS s3
,SUM(dept/10)
AS s4
,SUM(dept)/10
AS s5
FROM
staff;
Figure 238, SUM function examples
ANSWER
========================
S1
S2
S3
S4
S5
---- ---- ---- ---- ---1459 1459 326 134 145
ANSWER
==============================
A1 V1
V2 V3 V4
-- --------------- --- --- --41 +5.533012244E+2 553 553 582
SELECT AVG(dept) AS a1
,VARIANCE(dept) AS s1
,DEC(VARIANCE(dept),4,1) AS s2
,DEC(VARIANCE(ALL dept),4,1) AS s3
,DEC(VARIANCE(DISTINCT dept),4,1) AS s4
FROM
staff;
Figure 240, VARIANCE function examples
SELECT
FROM
WHERE
AND
ORDER BY
ANSWER
=================
JOB
ID SALARY
----- -- -------Clerk 80 13504.60
Mgr
10 18357.50
Mgr
50 20659.80
SELECT
ANSWER
======
SUMSAL
R
-------- 13504.60 1
31862.10 2
52521.90 3
SELECT
ANSWER
============================
JOB
ID SALARY
SUMSAL
R
----- -- -------- -------- Clerk 80 13504.60 13504.60 1
Mgr
10 18357.50 31862.10 2
Mgr
50 20659.80 52521.90 3
to get additional fields
SELECT
SELECT
SELECT
dpt.deptname
,emp.empno
,emp.lastname
,emp.salary
,SUM(salary) OVER(ORDER BY dpt.deptname ASC
,emp.salary
DESC
,emp.empno
ASC)
,ROW_NUMBER() OVER(ORDER BY dpt.deptname ASC
,emp.salary
DESC
,emp.empno
ASC)
FROM
employee
emp
,department dpt
WHERE
emp.firstnme LIKE '%S%'
AND
emp.workdept
= dpt.deptno
AND
dpt.admrdept LIKE 'A%'
AND
NOT EXISTS
(SELECT *
FROM
emp_act eat
WHERE
emp.empno
= eat.empno
AND
eat.emptime > 10)
ORDER BY dpt.deptname ASC
,emp.salary
DESC
,emp.empno
ASC;
Figure 246, Complicated query using OLAP functions
SELECT
id
,years
,salary
,RANK()
OVER(ORDER BY years) AS rank#
,DENSE_RANK() OVER(ORDER BY years) AS dense#
,ROW_NUMBER() OVER(ORDER BY years) AS row#
AS sumsal
AS row#
FROM
WHERE
AND
ORDER BY
staff
id
< 100
years IS NOT NULL
years;
ANSWER
===================================
ID YEARS SALARY
RANK# DENSE# ROW#
-- ----- -------- ----- ------ ---30
5 17506.75
1
1
1
40
6 18006.00
2
2
2
90
6 18001.75
2
2
3
10
7 18357.50
4
3
4
70
7 16502.83
4
3
5
20
8 18171.25
6
4
6
50
10 20659.80
7
5
7
Figure 248, Ranking functions example
SELECT
job
,years
,id
,name
,SMALLINT(RANK() OVER(ORDER BY job
ASC)) AS asc1
,SMALLINT(RANK() OVER(ORDER BY job
ASC
,years ASC)) AS asc2
,SMALLINT(RANK() OVER(ORDER BY job
ASC
,years ASC
,id
ASC)) AS asc3
,SMALLINT(RANK() OVER(ORDER BY job
DESC)) AS dsc1
,SMALLINT(RANK() OVER(ORDER BY job
DESC
,years DESC)) AS dsc2
,SMALLINT(RANK() OVER(ORDER BY job
DESC
,years DESC
,id
DESC)) AS Dsc3
,SMALLINT(RANK() OVER(ORDER BY job
ASC
,years DESC
,id
ASC)) AS mix1
,SMALLINT(RANK() OVER(ORDER BY job
DESC
,years ASC
,id
DESC)) AS mix2
FROM
staff
WHERE
id
< 150
AND
years IN (6,7)
AND
job
> 'L'
ORDER BY job
,years
,id;
ANSWER
================================================================
JOB
YEARS ID NAME
ASC1 ASC2 ASC3 DSC1 DSC2 DSC3 MIX1 MIX2
----- ----- --- ------- ---- ---- ---- ---- ---- ---- ---- ---Mgr
6 140 Fraye
1
1
1
4
6
6
3
4
Mgr
7 10 Sanders
1
2
2
4
4
5
1
6
Mgr
7 100 Plotz
1
2
3
4
4
4
2
5
Sales
6 40 O'Brien
4
4
4
1
2
3
5
2
Sales
6 90 Koonitz
4
4
5
1
2
2
6
1
Sales
7 70 Rothman
4
6
6
1
1
1
4
3
Figure 249, ORDER BY usage
SELECT
id
,years
,salary
,DENSE_RANK()
,DENSE_RANK()
,DENSE_RANK()
,DENSE_RANK()
,DENSE_RANK()
,DENSE_RANK()
FROM
staff
WHERE
id
< 100
ORDER BY years
,salary;
AS yr
OVER(ORDER
OVER(ORDER
OVER(ORDER
OVER(ORDER
OVER(ORDER
OVER(ORDER
BY
BY
BY
BY
BY
BY
years
years
years
years
years
years
ASC)
ASC NULLS
ASC NULLS
DESC)
DESC NULLS
DESC NULLS
AS a
FIRST) AS af
LAST ) AS al
AS d
FIRST) AS df
LAST ) AS dl
ANSWER
==================================
ID YR SALARY
A AF AL D DF DL
-- -- -------- -- -- -- -- -- -30 5 17506.75
1 2 1
6 6 5
90 6 18001.75
2 3 2
5 5 4
40 6 18006.00
2 3 2
5 5 4
70 7 16502.83
3 4 3
4 4 3
10 7 18357.50
3 4 3
4 4 3
20 8 18171.25
4 5 4
3 3 2
50 10 20659.80
5 6 5
2 2 1
80 - 13504.60
6 1 6
1 1 6
60 - 16808.30
6 1 6
1 1 6
Figure 250, Overriding the default null ordering sequence
SELECT
SELECT
id
,years AS yr
,salary
,RANK() OVER(PARTITION BY years
ORDER
BY salary) AS r1
FROM
staff
WHERE
id
< 80
AND
years IS NOT NULL
ORDER BY years
,salary;
Figure 252, Values ranked by subset of rows
ANSWER
=======
Y#1 Y#2
--- --5
6
ANSWER
=================
ID YR SALARY
R1
-- -- -------- -30 5 17506.75 1
40 6 18006.00 1
70 7 16502.83 1
10 7 18357.50 2
20 8 18171.25 1
50 0 20659.80 1
SELECT
id
,years
,salary
,SMALLINT(RANK() OVER(ORDER BY years ASC)) AS rank_a
,SMALLINT(RANK() OVER(ORDER BY years DESC)) AS rank_d
,SMALLINT(RANK() OVER(ORDER BY id, years)) AS rank_iy
FROM
STAFF
WHERE
id
< 100
AND
years IS NOT NULL
ORDER BY years;
Figure 253, Multiple rankings in same query
SELECT
id
,years
,name
,salary
,SMALLINT(RANK() OVER(ORDER
,SMALLINT(RANK() OVER(ORDER
,SMALLINT(RANK() OVER(ORDER
,SMALLINT(RANK() OVER(ORDER
,SMALLINT(RANK() OVER(ORDER
FROM
staff
WHERE
id
< 40
AND
years IS NOT NULL
ORDER BY 1;
Figure 254, Dumb rankings, SQL
ID YEARS NAME
SALARY
DUMB1
-- ----- -------- -------- ----10
7 Sanders
18357.50
1
20
8 Pernal
18171.25
3
30
5 Marenghi 17506.75
2
Figure 255, Dumb ranking, Answer
BY
BY
BY
BY
BY
SELECT
FROM
SUBSTR(name,3,2)))
salary / 1000))
years * ID))
rand()))
1))
DUMB2
----3
2
1
DUMB3
----1
3
2
xxx.*
,RANK()OVER(ORDER BY id) AS r2
(SELECT
id
,name
,RANK() OVER(ORDER BY id) AS r1
FROM
staff
WHERE
id
< 100
AND
years IS NOT NULL
DUMB4
----1
3
2
AS
AS
AS
AS
AS
dumb1
dumb2
dumb3
dumb4
dumb5
DUMB5
----1
1
1
ANSWER
================
ID NAME
R1 R2
-- ------- -- -40 O'Brien 4 1
50 Hanes
5 2
70 Rothman 6 3
90 Koonitz 7 4
)AS xxx
WHERE
id > 30
ORDER BY id;
Figure 256, Subsequent processing of ranked data
SELECT
id
ANSWER
,RANK() OVER(PARTITION BY dept
=================
ORDER BY salary DESC) AS r1
ID R1 SALARY
DP
,salary
-- -- -------- -,dept AS dp
50 1 20659.80 15
FROM
staff
10 1 18357.50 20
WHERE
id
< 80
40 1 18006.00 38
AND
years IS NOT NULL
20 2 18171.25 20
ORDER BY r1
ASC
30 2 17506.75 38
,salary DESC;
70 2 16502.83 15
Figure 257, Ordering rows by rank, using RANK function
SELECT
id
,(SELECT COUNT(*)
FROM
staff s2
WHERE s2.id
< 80
AND S2.YEARS IS NOT NULL
AND s2.dept
= s1.dept
AND s2.salary
>= s1.salary) AS R1
,SALARY
,dept AS dp
FROM
staff s1
WHERE
id
< 80
AND
years IS NOT NULL
ORDER BY r1
ASC
,salary DESC;
Figure 258, Ordering rows by rank, using sub-query
SELECT
ANSWER
=================
ID R1 SALARY
DP
-- -- -------- -50 1 20659.80 15
10 1 18357.50 20
40 1 18006.00 38
20 2 18171.25 20
30 2 17506.75 38
70 2 16502.83 15
id
ANSWER
,salary
==============
,dept AS dp
ID SALARY
DP
FROM
(SELECT
s1.*
-- -------- -,RANK() OVER(PARTITION BY dept
50 20659.80 15
ORDER BY salary DESC) AS r1
10 18357.50 20
FROM
staff s1
40 18006.00 38
WHERE
id
< 80
AND
years IS NOT NULL
)AS xxx
WHERE
r1 = 1
ORDER BY dp;
Figure 259, Get highest salary in each department, use RANK function
SELECT
id
ANSWER
,salary
==============
,dept AS dp
ID SALARY
DP
FROM
staff s1
-- -------- -WHERE
id
< 80
50 20659.80 15
AND
years IS NOT NULL
10 18357.50 20
AND
NOT EXISTS
40 18006.00 38
(SELECT *
FROM
staff s2
WHERE s2.id
< 80
AND s2.years IS NOT NULL
AND s2.dept
= s1.dept
AND s2.salary
> s1.salary)
ORDER BY DP;
Figure 260, Get highest salary in each department, use correlated sub-query
SELECT
id
ANSWER
,salary
==============
,dept AS dp
ID SALARY
DP
FROM
staff
-- -------- -WHERE
id
< 80
50 20659.80 15
AND
years IS NOT NULL
10 18357.50 20
AND
(dept, salary) IN
40 18006.00 38
(SELECT
dept, MAX(salary)
FROM
staff
WHERE
id
< 80
AND
years IS NOT NULL
GROUP BY dept)
ORDER BY dp;
Figure 261, Get highest salary in each department, use uncorrelated sub-query
SELECT
id
,name
,ROW_NUMBER() OVER()
AS r1
,ROW_NUMBER() OVER(ORDER BY id) AS r2
FROM
staff
WHERE
id
< 50
AND
years IS NOT NULL
ORDER BY id;
Figure 263, ORDER BY example, 1 of 3
ANSWER
=================
ID NAME
R1 R2
-- -------- -- -10 Sanders
1 1
20 Pernal
2 2
30 Marenghi 3 3
40 O'Brien
4 4
SELECT
id
,name
,ROW_NUMBER() OVER()
AS r1
,ROW_NUMBER() OVER(ORDER BY name) AS r2
FROM
staff
WHERE
id
< 50
AND
years IS NOT NULL
ORDER BY id;
Figure 264, ORDER BY example, 2 of 3
ANSWER
=================
ID NAME
R1 R2
-- -------- -- -10 Sanders
4 4
20 Pernal
3 3
30 Marenghi 1 1
40 O'Brien
2 2
SELECT
ANSWER
====================
ID NAME
R1 R2 R3
-- -------- -- -- -10 Sanders
1 1 4
20 Pernal
2 2 3
30 Marenghi 3 3 1
40 O'Brien
4 4 2
id
,name
,ROW_NUMBER() OVER()
AS r1
,ROW_NUMBER() OVER(ORDER BY ID)
AS r2
,ROW_NUMBER() OVER(ORDER BY NAME) AS r3
FROM
staff
WHERE
id
< 50
AND
years IS NOT NULL
ORDER BY id;
Figure 265, ORDER BY example, 3 of 3
SELECT
job
,years
,id
,name
,ROW_NUMBER() OVER(PARTITION BY job
ORDER
BY years) AS row#
,RANK()
OVER(PARTITION BY job
ORDER
BY years) AS rn1#
,DENSE_RANK() OVER(PARTITION BY job
ORDER
BY years) AS rn2#
FROM
staff
WHERE
id
< 150
AND
years IN (6,7)
ANSWER
AND
job
> 'L'
======================================
ORDER BY job
JOB
YEARS ID NAME
ROW# RN1# RN2#
,years;
----- ----- --- ------- ---- ---- ---Mgr
6 140 Fraye
1
1
1
Mgr
7 10 Sanders
2
2
2
Mgr
7 100 Plotz
3
2
2
Sales
6 40 O'Brien
1
1
1
Sales
6 90 Koonitz
2
1
1
Sales
7 70 Rothman
3
3
2
Figure 266, Use of PARTITION phrase
SELECT
FROM
*
(SELECT
id
,name
,ROW_NUMBER() OVER(ORDER BY id) AS r
staff
id
< 100
years IS NOT NULL
ANSWER
=============
ID NAME
R
-- -------- 10 Sanders 1
20 Pernal
2
30 Marenghi 3
FROM
WHERE
AND
)AS xxx
WHERE
r <= 3
ORDER BY id;
Figure 267, Select first 3 rows, using ROW_NUMBER function
SELECT
id
ANSWER
,name
=============
,ROW_NUMBER() OVER(ORDER BY id) AS r
ID NAME
R
FROM
staff
-- -------- WHERE
id
< 100
10 Sanders 1
AND
years IS NOT NULL
20 Pernal
2
ORDER BY id
30 Marenghi 3
FETCH FIRST 3 ROWS ONLY;
Figure 268, Select first 3 rows, using FETCH FIRST notation
SELECT
FROM
*
(SELECT
id
,name
,ROW_NUMBER() OVER(ORDER BY id) AS r
staff
id
< 200
years IS NOT NULL
ANSWER
=============
ID NAME
R
-- -------- 30 Marenghi 3
40 O'Brien 4
50 Hanes
5
70 Rothman 6
id
,name
,ROW_NUMBER() OVER(ORDER BY id) AS r
staff
id
< 200
years IS NOT NULL
ANSWER
==============
ID NAME
R
--- ------- -10 Sanders 1
70 Rothman 6
140 Fraye
11
190 Sneider 16
FROM
WHERE
AND
)AS xxx
WHERE
r BETWEEN 3 AND 6
ORDER BY id;
Figure 269, Select 3rd through 6th rows
SELECT
FROM
*
(SELECT
FROM
WHERE
AND
)AS xxx
WHERE
(r - 1) = ((r - 1) / 5) * 5
ORDER BY id;
Figure 270, Select every 5th matching row
SELECT
FROM
*
(SELECT
id
,name
,ROW_NUMBER() OVER(ORDER BY id DESC) AS r
FROM
staff
WHERE
id
< 200
AND
years IS NOT NULL
ANSWER
)AS xxx
==============
WHERE
r <= 2
ID NAME
R
ORDER BY id;
--- -------- 180 Abrahams 2
190 Sneider 1
Figure 271, Select last two rows
WITH
temp1(years, id, name, rnk, row) AS
(SELECT years
,id
,name
,RANK()
OVER(ORDER BY years)
,ROW_NUMBER() OVER(ORDER BY years, id)
FROM
staff
WHERE
id
< 200
AND
years IS NOT NULL
),
temp2(rnk) AS
(SELECT rnk
FROM
temp1
WHERE
row = 3
ANSWER
)
==========================
SELECT
temp1.*
YEARS ID NAME
RNK ROW
FROM
temp1
----- --- -------- --- --,temp2
3 180 Abrahams
1
1
WHERE
temp1.rnk <= temp2.rnk
4 170 Kermisch
2
2
ORDER BY years
5 30 Marenghi
3
3
,id;
5 110 Ngan
3
4
Figure 272, Select first "n" rows, or more if needed
inv#
customer#
sale_date
sale_value
500,000 rows
SELECT
s.*
FROM
invoice s
ORDER BY inv#
FETCH FIRST 5 ROWS ONLY;
Figure 275, Fetch first 5 rows - 0.313 elapsed seconds
SELECT
s.*
FROM
invoice s
ORDER BY inv#
FETCH FIRST 5 ROWS ONLY
OPTIMIZE FOR 5 ROWS;
Figure 276, Fetch first 5 rows - 0.281 elapsed seconds
SELECT
s.*
,ROW_NUMBER() OVER() AS row#
FROM
invoice s
ORDER BY inv#
FETCH FIRST 5 ROWS ONLY;
Figure 277, Fetch first 5 rows+ number rows - 0.672 elapsed seconds
SELECT
FROM
*
(SELECT
FROM
)xxx
s.*
,ROW_NUMBER() OVER() AS row#
invoice s
WHERE
row# <= 5
ORDER BY inv#;
Figure 278, Process and number 5 rows only - 0.000 elapsed seconds
SELECT
FROM
*
(SELECT
s.*
,ROW_NUMBER() OVER(ORDER BY inv#) AS row#
invoice s
FROM
)xxx
WHERE
row# <= 5
ORDER BY inv#;
Figure 279, Process and number 5 rows only - 0.281 elapsed seconds
SELECT
id
,name
,salary
,SUM(salary) OVER() AS sum_sal
,AVG(salary) OVER() AS avg_sal
,MIN(salary) OVER() AS min_sal
ID NAME
SALARY
-- -------- -------10 Sanders
18357.50
20 Pernal
18171.25
30 Marenghi 17506.75
40 O'Brien
18006.00
50 Hanes
20659.80
Figure 283, Aggregation
SUM_SAL
-------92701.30
92701.30
92701.30
92701.30
92701.30
function,
AVG_SAL
MIN_SAL
-------- -------18540.26 17506.75
18540.26 17506.75
18540.26 17506.75
18540.26 17506.75
18540.26 17506.75
basic usage, Answer
MAX_SAL
-------20659.80
20659.80
20659.80
20659.80
20659.80
#ROWS
----5
5
5
5
5
WITH
temp1 (id, name, salary) AS
(SELECT
id, name, salary
FROM
staff
WHERE
id < 60
),
temp2 (sum_sal, avg_sal, min_sal, max_sal, #rows) AS
(SELECT
SUM(salary)
,AVG(salary)
,MIN(salary)
,MAX(salary)
,COUNT(*)
FROM
temp1
)
SELECT
*
FROM
temp1
,temp2
ORDER BY id;
Figure 284, Select detailed data, plus summary data
SELECT
id
,name
,salary
,SUM(salary)
,SUM(salary)
,SUM(salary)
,SUM(salary)
FROM
staff
WHERE
id < 60
ORDER BY id;
OVER()
OVER(ORDER
OVER(ORDER
OVER(ORDER
RANGE
AS sum1
BY id * 0)
AS sum2
BY 'ABC')
AS sum3
BY 'ABC'
BETWEEN UNBOUNDED PRECEDING
AND UNBOUNDED FOLLOWING) AS sum4
ID NAME
SALARY
SUM1
SUM2
SUM3
SUM4
-- -------- -------- -------- -------- -------- -------10 Sanders
18357.50 92701.30 92701.30 92701.30 92701.30
20 Pernal
18171.25 92701.30 92701.30 92701.30 92701.30
30 Marenghi 17506.75 92701.30 92701.30 92701.30 92701.30
40 O'Brien
18006.00 92701.30 92701.30 92701.30 92701.30
50 Hanes
20659.80 92701.30 92701.30 92701.30 92701.30
Figure 286, Logically equivalent aggregation functions, Answer
SELECT
dept
,name
,salary
,SUM(salary) OVER(ORDER BY dept)
,SUM(salary) OVER(ORDER BY dept DESC)
,SUM(salary) OVER(ORDER BY dept, NAME)
,SUM(salary) OVER(ORDER BY dept DESC, name DESC)
,COUNT(*)
OVER(ORDER BY dept)
,COUNT(*)
OVER(ORDER BY dept, NAME)
FROM
staff
WHERE
id < 60
ORDER BY dept
,name;
Figure 287, Aggregation function, order by usage, SQL
DEPT NAME
SALARY
SUM1
SUM2
SUM3
---- -------- -------- -------- -------- -------15 Hanes
20659.80 20659.80 92701.30 20659.80
20 Pernal
18171.25 57188.55 72041.50 38831.05
20 Sanders 18357.50 57188.55 72041.50 57188.55
38 Marenghi 17506.75 92701.30 35512.75 74695.30
38 O'Brien 18006.00 92701.30 35512.75 92701.30
Figure 288, Aggregation function, order by usage,
SELECT
AS
AS
AS
AS
AS
AS
sum1
sum2
sum3
sum4
row1
row2
SUM4
ROW1 ROW2
-------- ---- ---92701.30
1
1
72041.50
3
2
53870.25
3
3
35512.75
5
4
18006.00
5
5
Answer
dept
,name
,years
,SMALLINT(SUM(years) OVER(ORDER BY dept))
AS d
,SMALLINT(SUM(years) OVER(ORDER BY dept, name))
AS dn
,SMALLINT(SUM(years) OVER(ORDER BY dept, name
ROWS
UNBOUNDED PRECEDING))AS dnu
,SMALLINT(SUM(years) OVER(ORDER BY dept, name
ROWS
3 PRECEDING))
AS
,SMALLINT(SUM(years) OVER(ORDER BY dept, name
ROWS
1 PRECEDING))
AS
,SMALLINT(SUM(years) OVER(ORDER BY dept, name
ROWS
0 PRECEDING))
AS
,SMALLINT(SUM(years) OVER(ORDER BY dept, name
ROWS
CURRENT ROW))
AS
,SMALLINT(SUM(years) OVER(ORDER BY dept DESC, name DESC
ROWS
1 PRECEDING))
AS
FROM
staff
WHERE
id
< 100
AND
years IS NOT NULL
ORDER BY dept
,name;
Figure 289, Starting ROWS usage. Implied end is current row, SQL
DEPT
---15
15
20
20
38
38
42
Figure
SELECT
NAME
YEARS
-----------Hanes
10
Rothman
7
Pernal
8
Sanders
7
Marenghi
5
O'Brien
6
Koonitz
6
290, Starting ROWS
dn3
dn1
dn0
dnc
dnx
D
DN
DNU
DN3
DN1
DN0
DNC
DNX
--------------17
10
10
10
10
10
10
17
17
17
17
17
17
7
7
15
32
25
25
25
15
8
8
15
32
32
32
32
15
7
7
12
43
37
37
27
12
5
5
11
43
43
43
26
11
6
6
12
49
49
49
24
12
6
6
6
usage. Implied end is current row, Answer
dept
,name
,years
,SMALLINT(SUM(years) OVER(ORDER BY dept, name))
,SMALLINT(SUM(years) OVER(ORDER BY dept, name
ROWS
UNBOUNDED PRECEDING))
,SMALLINT(SUM(years) OVER(ORDER BY dept, name
ROWS BETWEEN UNBOUNDED PRECEDING
AND CURRENT ROW))
,SMALLINT(SUM(years) OVER(ORDER BY dept, name
ROWS BETWEEN CURRENT ROW
AND CURRENT ROW))
,SMALLINT(SUM(years) OVER(ORDER BY dept, name
ROWS BETWEEN 1 PRECEDING
AND 1 FOLLOWING))
,SMALLINT(SUM(years) OVER(ORDER BY dept, name
ROWS BETWEEN 2 PRECEDING
AND 2 FOLLOWING))
,SMALLINT(SUM(years) OVER(ORDER BY dept, name
ROWS BETWEEN 3 PRECEDING
AND 3 FOLLOWING))
,SMALLINT(SUM(years) OVER(ORDER BY dept, name
ROWS BETWEEN CURRENT ROW
AND UNBOUNDED FOLLOWING))
,SMALLINT(SUM(years) OVER(ORDER BY dept, name
ROWS BETWEEN UNBOUNDED PRECEDING
AS uc1
AS uc2
AS uc3
AS cu1
AS pf1
AS pf2
AS pf3
AS cu1
DEPT NAME
YEARS UC1 UC2 UC3 CU1 PF1 PF2
---- -------- ----- --- --- --- --- --- --15 Hanes
10
10
10
10
10
17
25
15 Rothman
7
17
17
17
7
25
32
20 Pernal
8
25
25
25
8
22
37
20 Sanders
7
32
32
32
7
20
33
38 Marenghi
5
37
37
37
5
18
32
38 O'Brien
6
43
43
43
6
17
24
42 Koonitz
6
49
49
49
6
12
17
Figure 292, ROWS usage, with BETWEEN phrase, Answer
PF3
--32
37
43
49
39
32
24
CU1
--49
39
32
24
17
12
6
UU1
--49
49
49
49
49
49
49
SELECT
id
,name
,SMALLINT(SUM(id) OVER(ORDER BY id ASC
ROWS BETWEEN 1 PRECEDING
AND CURRENT ROW)) AS apc
,SMALLINT(SUM(id) OVER(ORDER BY id ASC
ROWS BETWEEN CURRENT ROW
AND 1 FOLLOWING)) AS acf
,SMALLINT(SUM(id) OVER(ORDER BY id DESC
ROWS BETWEEN 1 PRECEDING
AND CURRENT ROW)) AS dpc
,SMALLINT(SUM(id) OVER(ORDER BY id DESC
ROWS BETWEEN CURRENT ROW
AND 1 FOLLOWING)) AS dcf
FROM
staff
WHERE
id
< 50
AND
years IS NOT NULL
ANSWER
ORDER BY id;
===========================
ID NAME
APC ACF DPC DCF
-- -------- --- --- --- --10 Sanders
10 30 30 10
20 Pernal
30 50 50 30
30 Marenghi 50 70 70 50
40 O'Brien
70 40 40 70
Figure 293,BETWEEN and ORDER BY usage
ASC id (10,20,30,40)
READ ROWS, LEFT to RIGHT
==========================
1ST-ROW
========
2ND-ROW
========
3RD-ROW
========
4TH-ROW
========
10=10
10+20=30
10+20=30
20+30=50
20+30=40
30+40=70
30+40=70
40
=40
DESC id (40,30,20,10)
READ ROWS, RIGHT to LEFT
==========================
1 PRECEDING to CURRENT ROW
CURRENT ROW to 1 FOLLOWING
1ST-ROW
========
20+10=30
10
=10
2ND-ROW
========
30+20=50
20+10=30
3RD-ROW
========
40+30=70
30+20=50
4TH-ROW
========
40
=40
40+30=70
SELECT
dept
,name
,years
,SMALLINT(SUM(years) OVER(ORDER BY
ROWS BETWEEN
AND
,SMALLINT(SUM(years) OVER(ORDER BY
ROWS BETWEEN
AND
,SMALLINT(SUM(years) OVER(ORDER BY
RANGE BETWEEN
AND
,SMALLINT(SUM(years) OVER(ORDER BY
RANGE BETWEEN
AND
,SMALLINT(SUM(years) OVER(ORDER BY
RANGE BETWEEN
AND
,SMALLINT(SUM(years) OVER(ORDER BY
RANGE BETWEEN
AND
,SMALLINT(SUM(years) OVER(ORDER BY
RANGE BETWEEN
AND
FROM
staff
WHERE
id
< 100
AND
years IS NOT NULL
ORDER BY dept
,name;
Figure 295, RANGE usage, SQL
DEPT
-----15
15
20
20
38
NAME
------Hanes
Rothman
Pernal
Sanders
Marengh
YEARS
----10
7
8
7
5
ROW1
---10
17
15
15
12
ROW2
---10
17
25
22
20
RG01
---17
17
15
15
11
dept
1 PRECEDING
CURRENT ROW))
dept
2 PRECEDING
CURRENT ROW))
dept
1 PRECEDING
CURRENT ROW))
dept
10 PRECEDING
CURRENT ROW))
dept
20 PRECEDING
CURRENT ROW))
dept
10 PRECEDING
20 FOLLOWING))
dept
CURRENT ROW
20 FOLLOWING))
RG10
---17
17
32
32
11
RG20
---17
17
32
32
26
AS row1
AS row2
AS rg01
AS rg10
AS rg20
AS rg11
AS rg99
RG11
---32
32
43
43
17
RG99
---32
32
26
26
17
38 O'Brien
6
11
42 Koonitz
6
12
Figure 296, RANGE usage, Answer
18
17
11
6
11
17
26
17
17
17
dept
,name
,years
,SMALLINT(SUM(years) OVER(ORDER
BY dept))
,SMALLINT(SUM(years) OVER(ORDER
BY dept
ROWS 3 PRECEDING))
,SMALLINT(SUM(years) OVER(ORDER
BY dept
ROWS BETWEEN 1 PRECEDING
AND 1 FOLLOWING))
,SMALLINT(SUM(years) OVER(PARTITION BY dept))
,SMALLINT(SUM(years) OVER(PARTITION BY dept
ORDER
BY dept))
,SMALLINT(SUM(years) OVER(PARTITION BY dept
ORDER
BY dept
ROWS 1 PRECEDING))
,SMALLINT(SUM(years) OVER(PARTITION BY dept
ORDER
BY dept
ROWS 3 PRECEDING))
,SMALLINT(SUM(years) OVER(PARTITION BY dept
ORDER
BY dept
ROWS BETWEEN 1 PRECEDING
AND 1 FOLLOWING))
FROM
staff
WHERE
id BETWEEN 40 AND 120
AND
years IS NOT NULL
ORDER BY dept
,name;
Figure 297, PARTITION usage, SQL
17
6
SELECT
DEPT
----15
15
15
38
42
42
Figure
SELECT
FROM
NAME
YEARS
X
XO3 XO11
------- ----- ---- ---- ---Hanes
10
22
10
15
Ngan
5
22
15
22
Rothman
7
22
22
18
O'Brien
6
28
28
19
Koonitz
6
41
24
19
Plotz
7
41
26
13
298, PARTITION usage, Answer
dept
,SUM(years) AS sum
,AVG(years) AS avg
,COUNT(*)
AS row
staff
P
---22
22
22
6
13
13
PO
---22
22
22
6
13
13
PO1
---10
15
12
6
6
13
AS x
AS xo3
AS xo11
AS p
AS po
AS po1
AS po3
AS po11
PO3
---10
15
22
6
6
13
PO11
---15
22
12
6
13
13
ANSWER
================
DEPT SUM AVG ROW
---- --- --- --15 22
7
3
WHERE
id BETWEEN 40 AND 120
AND
years IS NOT NULL
GROUP BY dept;
Figure 299, Sample query using GROUP BY
SELECT
dept
,SUM(years) OVER(PARTITION BY dept) AS sum
,AVG(years) OVER(PARTITION BY dept) AS avg
,COUNT(*)
OVER(PARTITION BY dept) AS row
FROM
staff
WHERE
id BETWEEN 40 AND 120
AND
years IS NOT NULL
ORDER BY dept;
38
42
6
13
6
6
1
2
ANSWER
=================
DEPT SUM AVG ROW
----- --- --- --15 22
7
3
15 22
7
3
15 22
7
3
38
6
6
1
42 13
6
2
42 13
6
2
SELECT
DISTINCT dept
ANSWER
,SUM(years) OVER(PARTITION BY dept) AS sum
=================
,AVG(years) OVER(PARTITION BY dept) AS avg
DEPT SUM AVG ROW
,COUNT(*)
OVER(PARTITION BY dept) AS row
----- --- --- --FROM
staff
15 22
7
3
WHERE
id BETWEEN 40 AND 120
38
6
6
1
AND
years IS NOT NULL
42 13
6
2
ORDER BY dept;
Figure 301, Sample query using PARTITION and DISTINCT
D1
------2.4
0.0
1.8
F1
---------2.4e+000
0.0e+000
1.8e+000
S1
--2
0
1
C1
-----ABCDEF
ABCD
AB
V1
-----ABCDEF
ABCD
AB
TS1
-------------------------1996-04-22-23.58.58.123456
1996-08-15-15.15.15.151515
0001-01-01-00.00.00.000000
DT1
TM1
TC1
-----------------------------------------1996-04-22
23:58:58
1996-04-22-23.58.58.123456
1996-08-15
15:15:15
1996-08-15-15.15.15.151515
0001-01-01
00:00:00
0001-01-01-00.00.00.000000
Figure 303, SCALAR view, contents (3 rows)
SELECT d1
,ABS(D1)
,f1
,ABS(f1)
FROM
scalar;
AS
AS
AS
AS
d1
d2
f1
f2
SELECT c1
,ASCII(c1)
AS ac1
,ASCII(SUBSTR(c1,2)) AS ac2
FROM
scalar
WHERE c1 = 'ABCDEF';
Figure 305, ASCII function examples
ANSWER
================
C1
AC1 AC2
------ --- --ABCDEF
65
66
ANSWER
====================
BIG
-------------------1
256
65536
16777216
4294967296
1099511627776
281474976710656
72057594037927936
FLOAT1
DECIMAL1
BIGINT1
---------------------- ------------------- -------------------+1.23456789000000E+000
1.
1
+1.23456789000000E+002
123.
123
+1.23456789000000E+004
12345.
12345
+1.23456789000000E+006
1234567.
1234567
+1.23456789000000E+008
123456789.
123456788
+1.23456789000000E+010
12345678900.
12345678899
+1.23456789000000E+012
1234567890000.
1234567889999
+1.23456789000000E+014
123456789000000.
123456788999999
+1.23456789000000E+016
12345678900000000.
12345678899999996
+1.23456789000000E+018 1234567890000000000. 1234567889999999488
Figure 308, Convert FLOAT to DECIMAL and BIGINT, answer
SELECT d1
,CEIL(d1) AS d2
,f1
,CEIL(f1) AS f2
FROM
scalar;
Figure 311, CEIL function examples
SELECT
name
ANSWER
,CHAR(name,3)
=====================================
,comm
NAME
2
COMM
4
5
,CHAR(comm)
------- --- ------- -------- -------,CHAR(comm,'@')
James
Jam 128.20 00128.20 00128@20
FROM
staff
Koonitz Koo 1386.70 01386.70 01386@70
WHERE
id BETWEEN 80
Plotz
Plo
- AND 100
ORDER BY id;
Figure 313, CHAR function examples - characters and numbers
ANSWER
==========================================
INT
CHAR_INT CHAR_FLT
CHAR_DEC
-------- -------- ----------- -----------3 3
3.0E0
00000000003.
9 9
9.0E0
00000000009.
81 81
8.1E1
00000000081.
6561 6561
6.561E3
00000006561.
43046721 43046721 4.3046721E7 00043046721.
SELECT
SELECT
SELECT
FROM
==>
==>
==>
==>
ANSWER
==========
2005-11-30
30.11.2005
2005-11-30
11/30/2005
==>
==>
==>
==>
ANSWER
========
19.42.21
19.42.21
19:42:21
07:42 PM
ANSWER
==========================
2005-11-30-19.42.21.873002
Figure 318, CHAR function example - timestamp value
SELECT
CHAR(CURRENT TIMESTAMP)
sysibm.sysdummy1;
d2
,CHAR(d2)
AS cd2
,DIGITS(d2) AS dd2
FROM
(SELECT DEC(d1,4,1) AS d2
FROM
scalar
)AS xxx
ORDER BY 1;
Figure 319, DIGITS vs. CHAR
ANSWER
================
D2
CD2
DD2
---- ------ ----2.4 -002.4 0024
0.0 000.0 0000
1.8 001.8 0018
SELECT 'A'
AS "c"
,ASCII('A')
AS "c>n"
,CHR(ASCII('A')) AS "c>n>c"
,CHR(333)
AS "nl"
FROM
staff
WHERE id = 10;
Figure 320, CHR function examples
SELECT c1
,CLOB(c1)
AS cc1
,CLOB(c1,3) AS cc2
FROM
scalar;
ANSWER
=================
C C>N C>N>C NL
- --- ----- -A
65 A
ANSWER
===================
C1
CC1
CC2
------ ------ --ABCDEF ABCDEF ABC
ABCD
ABCD
ABC
AB
AB
AB
SELECT
id
,comm
,COALESCE(comm,0)
FROM
staff
WHERE
id < 30
ORDER BY id;
Figure 322, COALESCE function example
ANSWER
==================
ID COMM
3
-- ------ -----10
0.00
20 612.45 612.45
WITH temp1(c1,c2,c3) AS
(VALUES (CAST(NULL AS SMALLINT)
,CAST(NULL AS SMALLINT)
,CAST(10
AS SMALLINT)))
SELECT COALESCE(c1,c2,c3) AS cc1
,CASE
WHEN c1 IS NOT NULL THEN c1
WHEN c2 IS NOT NULL THEN c2
WHEN c3 IS NOT NULL THEN c3
END AS cc2
FROM
TEMP1;
Figure 323, COALESCE and equivalent CASE expression
SELECT COUNT(*)
AS #rows
ANSWER
========
CC1 CC2
--- --10
10
ANSWER
,MIN(id)
AS min_id
,COALESCE(MIN(id),-1) AS ccc_id
FROM
staff
WHERE id < 5;
Figure 324, NOT NULL field returning null value
===================
#ROWS MIN_ID CCC_ID
----- ------ -----0
-1
SELECT
ANSWER
===================
1
2
3
4
5
--- --- --- --- --AB AB AB ABC ABC
'A' || 'B'
,'A' CONCAT 'B'
,CONCAT('A','B')
,'A' || 'B' || 'C'
,CONCAT(CONCAT('A','B'),'C')
FROM
staff
WHERE
id = 10;
Figure 325, CONCAT function examples
WITH temp1(n1) AS
(VALUES (0)
UNION ALL
ANSWER
===============
COL1 COL2 COL3
---- ---- ----A
YYY A YYY
AE
OOO AEOOO
AE
YYY AEYYY
sequence
ANSWER
=======================
N1 RAN
COS
SIN
SELECT n1 + 10
FROM
temp1
WHERE
n1 < 90)
SELECT n1
,DEC(RADIANS(n1),4,3)
AS ran
,DEC(COS(RADIANS(n1)),4,3) AS cos
,DEC(SIN(RADIANS(n1)),4,3) AS sin
FROM
temp1;
-0
10
20
30
40
50
60
70
80
90
Figure 328, RADIAN, COS, and SIN functions example
----0.000
0.174
0.349
0.523
0.698
0.872
1.047
1.221
1.396
1.570
----1.000
0.984
0.939
0.866
0.766
0.642
0.500
0.342
0.173
0.000
----0.000
0.173
0.342
0.500
0.642
0.766
0.866
0.939
0.984
1.000
SELECT ts1
,DATE(ts1) AS dt1
FROM
scalar;
ANSWER
======================================
TS1
DT1
-------------------------- ---------1996-04-22-23.58.58.123456 1996-04-22
1996-08-15-15.15.15.151515 1996-08-15
0001-01-01-00.00.00.000000 0001-01-01
Figure 330, DATE function example - timestamp input
WITH temp1(n1) AS
(VALUES
(000001)
,(728000)
,(730120))
SELECT n1
,DATE(n1) AS d1
FROM
temp1;
Figure 331, DATE function example - numeric input
SELECT dt1
,DAY(dt1) AS day1
FROM
scalar
WHERE DAY(dt1) > 10;
Figure 332, DAY function examples
ANSWER
===================
N1
D1
------- ---------1 0001-01-01
728000 1994-03-13
730120 2000-01-01
ANSWER
================
DT1
DAY1
---------- ---1996-04-22
22
1996-08-15
15
SELECT
dt1
,DAY(dt1)
,dt1 -'1996-04-30'
,DAY(dt1 -'1996-04-30')
FROM
scalar
WHERE
DAY(dt1) > 10
ORDER BY dt1;
Figure 333, DAY function, using
AS day1
AS dur2
AS day2
ANSWER
=========================
DT1
DAY1 DUR2 DAY2
---------- ---- ---- ---1996-04-22
22 -8.
-8
1996-08-15
15 315.
15
date-duration input
SELECT dt1
,DAYNAME(dt1)
AS dy1
,LENGTH(DAYNAME(dt1)) AS dy2
FROM
scalar
WHERE DAYNAME(dt1) LIKE '%a%y'
ORDER BY dt1;
ANSWER
========================
DT1
DY1
DY2
---------- ------- --0001-01-01 Monday
6
1996-04-22 Monday
6
1996-08-15 Thursday
8
SELECT
dt1
,DAYOFWEEK(dt1) AS dwk
,DAYNAME(dt1)
AS dnm
FROM
scalar
ORDER BY dwk
,dnm;
ANSWER
=========================
DT1
DWK DNM
---------- --- -------0001-01-01
2 Monday
1996-04-22
2 Monday
1996-08-15
5 Thursday
WITH
temp1 (n) AS
(VALUES (0)
UNION ALL
SELECT n+1
FROM
temp1
WHERE n < 9),
temp2 (dt1) AS
(VALUES(DATE('1999-12-25'))
,(DATE('2000-12-24'))),
temp3 (dt2) AS
(SELECT dt1 + n DAYS
FROM
temp1
,temp2)
SELECT
CHAR(dt2,ISO)
,SUBSTR(DAYNAME(dt2),1,3)
,WEEK(dt2)
,DAYOFWEEK(dt2)
AS
AS
AS
AS
date
day
w
d
ANSWER
========================
DATE
DAY W D WI I
---------- --- -- - -- 1999-12-25 Sat 52 7 51 6
1999-12-26 Sun 53 1 51 7
1999-12-27 Mon 53 2 52 1
1999-12-28 Tue 53 3 52 2
1999-12-29 Wed 53 4 52 3
1999-12-30 Thu 53 5 52 4
1999-12-31 Fri 53 6 52 5
2000-01-01 Sat 1 7 52 6
2000-01-02 Sun 2 1 52 7
2000-01-03 Mon 2 2 1 1
2000-12-24 Sun 53 1 51 7
2000-12-25 Mon 53 2 52 1
2000-12-26 Tue 53 3 52 2
2000-12-27 Wed 53 4 52 3
,WEEK_ISO(dt2)
,DAYOFWEEK_ISO(dt2)
FROM
temp3
ORDER BY 1;
AS wi
AS i
2000-12-28
2000-12-29
2000-12-30
2000-12-31
2001-01-01
2001-01-02
Thu
Fri
Sat
Sun
Mon
Tue
53
53
53
54
1
1
5
6
7
1
2
3
52
52
52
52
1
1
4
5
6
7
1
2
SELECT
dt1
,DAYOFYEAR(dt1) AS dyr
FROM
scalar
ORDER BY dyr;
ANSWER
===============
DT1
DYR
---------- --0001-01-01
1
1996-04-22 113
1996-08-15 228
SELECT
dt1
,DAYS(dt1) AS dy1
FROM
scalar
ORDER BY dy1
,dt1;
ANSWER
==================
DT1
DY1
---------- -----0001-01-01
1
1996-04-22 728771
1996-08-15 728886
SELECT
FROM
WHERE
DBPARTITIONNUM(id) AS dbnum
staff
id = 10;
ANSWER
======
DBNUM
----0
WITH temp1(n1,n2,c1,c2) AS
(VALUES
(123
,1E2
,'123.4'
,'567$8'))
SELECT DEC(n1,3)
AS dec1
,DEC(n2,4,1)
AS dec2
,DEC(c1,4,1)
AS dec3
,DEC(c2,4,1,'$') AS dec4
FROM
temp1;
Figure 342, DECIMAL function examples
ANSWER
==========================
DEC1 DEC2
DEC3
DEC4
----- ------ ------ -----123. 100.0 123.4 567.8
SELECT
id
,name
,DECRYPT_CHAR(name2,'CLUELESS')
AS name3
,GETHINT(name2)
AS hint
,name2
FROM
(SELECT id
,name
,ENCRYPT(name,'CLUELESS','MY BOSS') AS name2
FROM
staff
WHERE id < 30
)AS xxx
ORDER BY id;
Figure 344, DECRYPT_CHAR function example
SELECT
a.name
AS n1
,SOUNDEX(a.name) AS s1
,b.name
AS n2
,SOUNDEX(b.name) AS s2
,DIFFERENCE
(a.name,b.name) AS df
FROM
staff a
,staff b
WHERE
a.id = 10
AND
b.id > 150
AND
b.id < 250
ORDER BY df DESC
,n2 ASC;
Figure 345, DIFFERENCE function example
ANSWER
==============================
N1
S1
N2
S2
DF
------- ---- --------- ---- -Sanders S536 Sneider
S536 4
Sanders S536 Smith
S530 3
Sanders S536 Lundquist L532 2
Sanders S536 Daniels
D542 1
Sanders S536 Molinare M456 1
Sanders S536 Scoutten S350 1
Sanders S536 Abrahams A165 0
Sanders S536 Kermisch K652 0
Sanders S536 Lu
L000 0
SELECT s1
,DIGITS(s1) AS ds1
,d1
,DIGITS(d1) AS dd1
FROM
scalar;
Figure 346, DIGITS function examples
ANSWER
=========================
S1
DS1
D1
DD1
------ ----- ----- ---2 00002
-2.4 024
0 00000
0.0 000
1 00001
1.8 018
WITH temp1(c1,d1) AS
ANSWER (output shortened)
(VALUES ('12345',12.4)
==================================
,('-23.5',1234)
C1D
D1D
,('1E+45',-234)
---------------- ---------------,('-2e05',+2.4))
+1.23450000E+004 +1.24000000E+001
SELECT DOUBLE(c1) AS c1d
-2.35000000E+001 +1.23400000E+003
,DOUBLE(d1) AS d1d
+1.00000000E+045 -2.34000000E+002
FROM
temp1;
-2.00000000E+005 +2.40000000E+000
Figure 347, DOUBLE function examples
SELECT
id
,name
,ENCRYPT(name,'THAT IDIOT','MY BROTHER') AS name2
FROM
staff
WHERE ID < 30
ORDER BY id;
Figure 349, ENCRYPT function example
WITH temp1(n1) AS
(VALUES (0)
UNION ALL
SELECT n1 + 1
FROM
temp1
WHERE
n1 < 10)
SELECT n1
,EXP(n1)
AS e1
,SMALLINT(EXP(n1)) AS e2
FROM
temp1;
ANSWER
==============================
N1 E1
E2
-- --------------------- ----0 +1.00000000000000E+0
1
1 +2.71828182845904E+0
2
2 +7.38905609893065E+0
7
3 +2.00855369231876E+1
20
4 +5.45981500331442E+1
54
5 +1.48413159102576E+2
148
6
7
8
9
10
SELECT d1
,FLOOR(d1) AS d2
,f1
,FLOOR(f1) AS f2
FROM
scalar;
+4.03428793492735E+2
403
+1.09663315842845E+3 1096
+2.98095798704172E+3 2980
+8.10308392757538E+3 8103
+2.20264657948067E+4 22026
SELECT
id
,GENERATE_UNIQUE()
AS unique_val#1
,DEC(HEX(GENERATE_UNIQUE()),26) AS unique_val#2
FROM
staff
WHERE
id < 50
ORDER BY id;
ANSWER
================= ===========================
ID UNIQUE_VAL#1
UNIQUE_VAL#2
-- -------------- --------------------------NOTE: 2ND FIELD =>
10
20011017191648990521000000.
IS UNPRINTABLE. =>
20
20011017191648990615000000.
30
20011017191648990642000000.
40
20011017191648990669000000.
Figure 352, GENERATE_UNIQUE function examples
SELECT
u1
,SUBSTR(u1,20,1) CONCAT SUBSTR(u1,19,1)
SUBSTR(u1,18,1) CONCAT SUBSTR(u1,17,1)
SUBSTR(u1,16,1) CONCAT SUBSTR(u1,15,1)
SUBSTR(u1,14,1) CONCAT SUBSTR(u1,13,1)
SUBSTR(u1,12,1) CONCAT SUBSTR(u1,11,1)
SUBSTR(u1,10,1) CONCAT SUBSTR(u1,09,1)
SUBSTR(u1,08,1) CONCAT SUBSTR(u1,07,1)
SUBSTR(u1,06,1) CONCAT SUBSTR(u1,05,1)
SUBSTR(u1,04,1) CONCAT SUBSTR(u1,03,1)
SUBSTR(u1,02,1) CONCAT SUBSTR(u1,01,1)
FROM
(SELECT HEX(GENERATE_UNIQUE()) AS u1
FROM
staff
WHERE id < 50) AS xxx
ORDER BY u2;
CONCAT
CONCAT
CONCAT
CONCAT
CONCAT
CONCAT
CONCAT
CONCAT
CONCAT
AS U2
ANSWER
================================================
U1
U2
-------------------------- -------------------20000901131649119940000000 04991194613110900002
20000901131649119793000000 39791194613110900002
20000901131649119907000000 70991194613110900002
20000901131649119969000000 96991194613110900002
Figure 353, GENERATE_UNIQUE output, characters reversed to make pseudo-random
SELECT
u1
,SUBSTR(reverse(CHAR(u1)),7,20) AS u2
FROM
(SELECT HEX(GENERATE_UNIQUE()) AS u1
FROM
STAFF
WHERE ID < 50) AS xxx
ORDER BY U2;
Figure 354, GENERATE_UNIQUE output, characters reversed using function
SELECT
id
,name
,GETHINT(name2) AS hint
FROM
(SELECT id
,name
,ENCRYPT(name,'THAT IDIOT','MY BROTHER') AS name2
FROM
staff
WHERE id < 30
ANSWER
)AS xxx
=====================
ORDER BY id;
ID NAME
HINT
-- ------- ---------10 Sanders MY BROTHER
20 Pernal MY BROTHER
Figure 355, GETHINT function example
SELECT
FROM
WHERE
HASHEDVALUE(id) AS hvalue
staff
id = 10;
WITH temp1(n1) AS
(VALUES (-3)
UNION ALL
ANSWER
======
HVALUE
-----0
ANSWER
===============================
S SHX DHX
FHX
SELECT n1 + 1
FROM
temp1
WHERE
n1 < 3)
SELECT SMALLINT(n1)
,HEX(SMALLINT(n1))
,HEX(DEC(n1,4,0))
,HEX(DOUBLE(n1))
FROM
temp1;
Figure 357, HEX function
---------------00000000000008C0
00000000000000C0
000000000000F0BF
0000000000000000
000000000000F03F
0000000000000040
0000000000000840
SELECT c1
,HEX(c1) AS chx
,v1
,HEX(v1) AS vhx
FROM
scalar;
ANSWER
=======================================
C1
CHX
V1
VHX
------ ------------ ------ -----------ABCDEF 414243444546 ABCDEF 414243444546
ABCD
414243442020 ABCD
41424344
AB
414220202020 AB
4142
Figure 358, HEX function examples, character & varchar
SELECT dt1
,HEX(dt1) AS dthx
,tm1
,HEX(tm1) AS tmhx
FROM
scalar;
ANSWER
===================================
DT1
DTHX
TM1
TMHX
---------- -------- -------- -----1996-04-22 19960422 23:58:58 235858
1996-08-15 19960815 15:15:15 151515
0001-01-01 00010101 00:00:00 000000
Figure 359, HEX function examples, date & time
SELECT
tm1
,HOUR(tm1) AS hr
FROM
scalar
ORDER BY tm1;
ANSWER
============
TM1
HR
-------- -00:00:00
0
15:15:15 15
23:58:58 23
ANSWER
======
IDVAL
----1.
SELECT name
,INSERT(name,3,2,'A')
,INSERT(name,3,2,'AB')
,INSERT(name,3,2,'ABC')
FROM
staff
WHERE id < 40;
SELECT d1
,INTEGER(d1)
,INT('+123')
,INT('-123')
,INT(' 123 ')
FROM
scalar;
ANSWER
====================================
D1
2
3
4
5
----- ----- ------ ------ ------2.4
-2
123
-123
123
0.0
0
123
-123
123
1.8
1
123
-123
123
Figure 364, INTEGER function examples
WITH temp1(dt1) AS
(VALUES ('0001-01-01-00.00.00')
,('1752-09-10-00.00.00')
,('1993-01-03-00.00.00')
,('1993-01-03-23.59.59'))
SELECT DATE(dt1)
AS dt
,DAYS(dt1)
AS dy
,JULIAN_DAY(dt1) AS dj
FROM
temp1;
Figure 365, JULIAN_DAY function example
ANSWER
=========================
DT
DY
DJ
---------- ------ ------0001-01-01
1 1721426
1752-09-10 639793 2361218
1993-01-03 727566 2448991
1993-01-03 727566 2448991
SELECT
bd
,JULIAN_DAY(bd)
,(1461 * (YEAR(bd) + 4800 +
(MONTH(bd)-14)/12))/4
+( 367 * (MONTH(bd)- 2
- 12*((MONTH(bd)-14)/12)))/12
-(
3 * ((YEAR(bd) + 4900 +
(MONTH(bd)-14)/12)/100))/4
+DAY(bd) - 32075
FROM
(SELECT birthdate AS bd
FROM
employee
WHERE midinit = 'R'
ANSWER
) AS xxx
==========================
ORDER BY bd;
BD
2
3
---------- ------- ------1926-05-17 2424653 2424653
1936-03-28 2428256 2428256
1946-07-09 2432011 2432011
1955-04-12 2435210 2435210
Figure 366, JULIAN_DAY function examples
ANSWER
=============================
DT
DJ1
DJ2
---------- ---------- ------1997-01-01 1996-12-17 1997001
1997-01-02 1996-12-18 1997002
1997-12-31 1997-12-16 1997365
WITH temp1(dt1) AS
(VALUES ('1997-01-01')
,('1997-01-02')
,('1997-12-31'))
SELECT DATE(dt1) AS dt
,DATE(dt1) - 15 DAYS AS dj1
,YEAR(dt1) * 1000 + DAYOFYEAR(dt1) AS dj2
FROM
temp1;
Figure 367, Julian Date outputs
SELECT name
,LCASE(name) AS lname
,UCASE(name) AS uname
FROM
staff
WHERE id < 30;
Figure 368, LCASE function example
WITH temp1(c1) AS
(VALUES (' ABC')
,(' ABC ')
,('ABC '))
SELECT c1
,LEFT(c1,4)
AS c2
,LENGTH(LEFT(c1,4)) AS l2
ANSWER
=========================
NAME
LNAME
UNAME
------- ------- ------Sanders sanders SANDERS
Pernal
pernal
PERNAL
ANSWER
================
C1
C2
L2
----- ----- -ABC
AB
4
ABC
ABC
4
ABC
ABC
4
FROM
temp1;
Figure 369, LEFT function examples
SELECT LENGTH(d1)
,LENGTH(f1)
,LENGTH(s1)
,LENGTH(c1)
,LENGTH(RTRIM(c1))
FROM
scalar;
Figure 370, LENGTH function examples
WITH temp1(n1) AS
(VALUES (1),(123),(1234)
,(12345),(123456))
SELECT n1
,LOG(n1) AS l1
FROM
temp1;
ANSWER
=======================
1
2
3
4
5
--- --- --- --- --2
8
2
6
6
2
8
2
6
4
2
8
2
6
2
ANSWER
===============================
N1
L1
------ ----------------------1
+0.00000000000000E+000
123
+4.81218435537241E+000
1234
+7.11801620446533E+000
12345
+9.42100640177928E+000
123456
+1.17236400962654E+001
SELECT c1
,LOCATE('D', c1)
,LOCATE('D', c1,2)
,LOCATE('EF',c1)
,LOCATE('A', c1,2)
FROM
scalar;
ANSWER
==========================
C1
2
3
4
5
------ --- --- --- --ABCDEF
4
4
5
0
ABCD
4
4
0
0
AB
0
0
0
0
WITH temp1(n1) AS
(VALUES (1),(123),(1234)
,(12345),(123456))
SELECT n1
ANSWER
===============================
N1
L1
------ -----------------------
,LOG10(n1) AS l1
temp1;
FROM
WITH temp1(c1) AS
(VALUES (' ABC')
,(' ABC ')
,('ABC '))
SELECT c1
,LTRIM(c1)
AS c2
,LENGTH(LTRIM(c1)) AS l2
FROM
temp1;
Figure 375, LTRIM function example
1
123
1234
12345
123456
+0.00000000000000E+000
+2.08990511143939E+000
+3.09131515969722E+000
+4.09149109426795E+000
+5.09151220162777E+000
ANSWER
================
C1
C2
L2
----- ----- -ABC ABC
3
ABC
ABC
4
ABC
ABC
5
SELECT
ts1
,MICROSECOND(ts1)
FROM
scalar
ORDER BY ts1;
ANSWER
======================================
TS1
2
-------------------------- ----------0001-01-01-00.00.00.000000
0
1996-04-22-23.58.58.123456
123456
1996-08-15-15.15.15.151515
151515
Figure 376, MICROSECOND function example
SELECT ts1
ANSWER
,MIDNIGHT_SECONDS(ts1)
======================================
,HOUR(ts1)*3600 +
TS1
2
3
MINUTE(ts1)*60 +
-------------------------- ----- ----SECOND(ts1)
0001-01-01-00.00.00.000000
0
0
FROM
scalar
1996-04-22-23.58.58.123456 86338 86338
ORDER BY ts1;
1996-08-15-15.15.15.151515 54915 54915
Figure 377, MIDNIGHT_SECONDS function example
ANSWER
==============
MS
TM
----- -------0 00:00:00
54915 15:15:15
86338 23:58:58
SELECT ms
,SUBSTR(DIGITS(ms/3600
),9) ||
SUBSTR(DIGITS((ms-((MS/3600)*3600))/60 ),9) ||
SUBSTR(DIGITS(ms-((MS/60)*60)
),9) AS
FROM
temp1
ORDER BY 1;
Figure 378, Convert MIDNIGHT_SECONDS output back to a
':' ||
':' ||
tm
time value
SELECT
ts1
,MINUTE(ts1)
FROM
scalar
ORDER BY ts1;
ANSWER
======================================
TS1
2
-------------------------- ----------0001-01-01-00.00.00.000000
0
1996-04-22-23.58.58.123456
58
1996-08-15-15.15.15.151515
15
Figure 379, MINUTE function example
WITH temp1(n1,n2) AS
(VALUES (-31,+11)
UNION ALL
SELECT n1 + 13
,n2 - 4
FROM
temp1
WHERE
n1 < 60
)
SELECT
n1
,n2
,n1/n2
,n1-((n1/n2)*n2)
,MOD(n1,n2)
FROM
temp1
ORDER BY 1;
Figure 380, MOD function
SELECT
dt1
,MONTH(dt1)
,MONTHNAME(dt1)
FROM
scalar
ORDER BY dt1;
AS div
AS md1
AS md2
ANSWER
=======================
N1
N2
DIV MD1 MD2
--- --- --- --- ---31
11
-2
-9
-9
-18
7
-2
-4
-4
-5
3
-1
-2
-2
8
-1
-8
0
0
21
-5
-4
1
1
34
-9
-3
7
7
47 -13
-3
8
8
60 -17
-3
9
9
example
ANSWER
=======================
DT1
2
3
---------- -- ------0001-01-01
1 January
1996-04-22
4 April
1996-08-15
8 August
Figure 381, MONTH and MONTHNAME functions example
>>
>>
>>
>>
>>
ANSWER
========
1234.
1234.
1522756.
1522756.
1522756.
<--MULTIPLY_ALT->
RESULT
RESULT
SCALE
PRECSION
INPUT#1
INPUT#2
"*" OPERATOR MULTIPLY_ALT
TRUNCATD TRUNCATD
========== ========== ============ ============
======== =======
DEC(05,00) DEC(05,00) DEC(10,00)
DEC(10,00)
NO
NO
DEC(10,05) DEC(11,03) DEC(21,08)
DEC(21,08)
NO
NO
DEC(20,15) DEC(21,13) DEC(31,28)
DEC(31,18)
YES
NO
DEC(26,23) DEC(10,01) DEC(31,24)
DEC(31,19)
YES
NO
DEC(31,03) DEC(15,08) DEC(31,11)
DEC(31,03)
YES
YES
Figure 383, Decimal multiplication - same output lengths
SELECT s1
,NULLIF(s1,0)
,c1
,NULLIF(c1,'AB')
FROM
scalar
WHERE NULLIF(0,0) IS NULL;
Figure 384, NULLIF function examples
SELECT
FROM
WHERE
PARTITION(id) AS pp
staff
id = 10;
SELECT
c1
,POSSTR(c1,' ') AS p1
,POSSTR(c1,'CD') AS p2
,POSSTR(c1,'cd') AS p3
FROM
scalar
ORDER BY 1;
Figure 385, POSSTR function examples
ANSWER
=====================
S1 2
C1
4
--- --- ------ ------2 -2 ABCDEF ABCDEF
0
- ABCD
ABCD
1
1 AB
-
ANSWER
======
PP
-0
ANSWER
==================
C1
P1 P2 P3
------ -- -- -AB
3
0
0
ABCD
5
3
0
ABCDEF
0
3
0
SELECT c1
,POSSTR(c1,' ')
AS p1
,LOCATE(' ',c1)
AS l1
,POSSTR(c1,'CD') AS p2
,LOCATE('CD',c1) AS l2
,POSSTR(c1,'cd') AS p3
,LOCATE('cd',c1) AS l3
,LOCATE('D',c1,2) AS l4
FROM
scalar
ORDER BY 1;
Figure 386, POSSTR vs. LOCATE functions
WITH temp1(n1) AS
(VALUES (1),(10),(100))
SELECT n1
,POWER(n1,1) AS p1
,POWER(n1,2) AS p2
,POWER(n1,3) AS p3
FROM
temp1;
Figure 387, POWER function examples
ANSWER
===========================
C1
P1 L1 P2 L2 P3 L3 L4
------ -- -- -- -- -- -- -AB
3 3 0 0 0 0 0
ABCD
5 5 3 3 0 0 4
ABCDEF 0 0 3 3 0 0 4
ANSWER
===============================
N1
P1
P2
P3
------- ------- ------- ------1
1
1
1
10
10
100
1000
100
100
10000 1000000
SELECT s1
,CASE
WHEN s1 < 1 THEN s1
ELSE RAISE_ERROR('80001',c1)
END AS s2
FROM
scalar;
Figure 389, RAISE_ERROR function example
ANSWER
==============
S1
S2
------ ------2
-2
0
0
SQLSTATE=80001
ANSWER
=============
SELECT
COUNT(*)
,COUNT(DISTINCT ran)
,DEC(AVG(ran),7,6)
,DEC(STDDEV(ran),7,6)
,DEC(MIN(ran),7,6)
,DEC(MAX(ran),7,6)
,DEC(MAX(ran),7,6) DEC(MIN(ran),7,6)
,DEC(VAR(ran),7,6)
FROM
temp;
Figure 390, Sample output from
AS
AS
AS
AS
AS
AS
#rows
#values
avg_ran
std_dev
min_ran
max_ran
AS range
AS variance
==>
==>
==>
100000
31242
0.499838
0.288706
0.000000
1.000000
1.000000
0.083351
RAND function
SELECT
deptno AS dno
,RAND(0) AS ran
FROM
department
WHERE
deptno < 'E'
ORDER BY 1;
ANSWER
===========================
DNO RAN
--- ---------------------A00 +1.15970336008789E-003
B01 +2.35572374645222E-001
C01 +6.48152104251228E-001
D01 +7.43736075930052E-002
D11 +2.70241401409955E-001
D21 +3.60026856288339E-001
Figure 391, Make reproducible random numbers (use seed)
SELECT
deptno AS dno
,RAND() AS ran
FROM
department
WHERE
deptno < 'D'
ORDER BY 1;
ANSWER
===========================
DNO RAN
--- ---------------------A00 +2.55287331766717E-001
B01 +9.85290078432569E-001
C01 +3.18918424024171E-001
Figure 392, Make non-reproducible random numbers (no seed)
ANSWER
===================
COL1 COL2 COL3
---- ---- ------0
0 9342.32
1
250 8916.28
2
310 5430.76
3
150 5996.88
4
110 8066.34
5
50 5589.77
6
130 8602.86
7
340
184.94
8
310 5441.14
9
70 9267.55
SELECT
id
,name
FROM
staff
WHERE
RAND() < 0.1
ORDER BY id;
Figure 395, Randomly select 10% of matching rows
SELECT
id
,name
FROM
(SELECT s.*
,ROW_NUMBER() OVER(ORDER BY RAND()) AS r
FROM
staff s
)AS xxx
WHERE
r <= 5
ORDER BY id;
Figure 396, Select five random rows
UPDATE staff
SET
salary = RAND()*10000
WHERE
id < 50;
Figure 397, Use RAND to assign random salaries
ANSWER
============
ID NAME
--- -------140 Fraye
190 Sneider
290 Quill
ANSWER
============
ID NAME
--- -------10 Sanders
30 Marenghi
190 Sneider
270 Lea
280 Wilson
ANSWERS
================================
SELECT n1
AS dec
=> 1234567890.123456789012345678901
,DOUBLE(n1) AS dbl
=>
1.23456789012346e+009
,REAL(n1)
AS rel
=>
1.234568e+009
,INTEGER(n1) AS int
=>
1234567890
,BIGINT(n1) AS big
=>
1234567890
FROM
(SELECT 1234567890.123456789012345678901 AS n1
FROM
staff
WHERE id = 10) AS xxx;
Figure 398, REAL and other numeric function examples
SELECT
id
,CHAR(REPEAT(name,3),40)
FROM
staff
WHERE
id < 40
ORDER BY id;
ANSWER
===========================
ID 2
-- -----------------------10 SandersSandersSanders
20 PernalPernalPernal
30 MarenghiMarenghiMarenghi
SELECT c1
,REPLACE(c1,'AB','XY') AS r1
,REPLACE(c1,'BA','XY') AS r2
FROM
scalar;
ANSWER
======================
C1
R1
R2
------ ------ -----ABCDEF XYCDEF ABCDEF
ABCD
XYCD
ABCD
AB
XY
AB
SELECT c1
,REPLACE(REPLACE(
REPLACE(REPLACE(c1,
'AB','XY'),'ab','XY'),
'Ab','XY'),'aB','XY')
FROM
scalar;
ANSWER
==============
C1
R1
------ -----ABCDEF XYCDEF
ABCD
XYCD
AB
XY
WITH temp1(c1) AS
(VALUES (' ABC')
,(' ABC ')
,('ABC '))
SELECT c1
,RIGHT(c1,4)
AS c2
,LENGTH(RIGHT(c1,4)) as l2
FROM
temp1;
Figure 404, RIGHT function examples
ANSWER
================
C1
C2
L2
----- ----- -ABC
ABC
4
ABC
ABC
4
ABC
BC
4
ANSWER
===============================================
D1
P2
P1
P0
N1
N2
------- ------- ------- ------- ------- ------123.400 123.400 123.400 123.000 120.000 100.000
23.450 23.450 23.400 23.000 20.000
0.000
3.456
3.460
3.500
3.000
0.000
0.000
0.056
0.060
0.100
0.000
0.000
0.000
WITH temp1(d1) AS
(VALUES (123.400)
,( 23.450)
,( 3.456)
,(
.056))
SELECT d1
,DEC(ROUND(d1,+2),6,3) AS p2
,DEC(ROUND(d1,+1),6,3) AS p1
,DEC(ROUND(d1,+0),6,3) AS p0
,DEC(ROUND(d1,-1),6,3) AS n1
,DEC(ROUND(d1,-2),6,3) AS n2
FROM
temp1;
Figure 405, ROUND function examples
SELECT c1
,RTRIM(c1)
AS r1
,LENGTH(c1)
AS r2
,LENGTH(RTRIM(c1)) AS r3
FROM
scalar;
Figure 406, RTRIM function example
ANSWER
======================
C1
R1
R2 R3
------ ------ -- -ABCDEF ABCDEF
6
6
ABCD
ABCD
6
4
AB
AB
6
2
SELECT d1
,SIGN(d1)
,f1
,SIGN(f1)
FROM
scalar;
WITH temp1(n1) AS
(VALUES (0)
UNION ALL
SELECT n1 + 10
FROM
temp1
WHERE
n1 < 80)
SELECT n1
,DEC(RADIANS(n1),4,3)
AS ran
,DEC(SIN(RADIANS(n1)),4,3) AS sin
,DEC(TAN(RADIANS(n1)),4,3) AS tan
FROM
temp1;
Figure 408, SIN function example
ANSWER
=======================
N1 RAN
SIN
TAN
-- ----- ----- ----0 0.000 0.000 0.000
10 0.174 0.173 0.176
20 0.349 0.342 0.363
30 0.523 0.500 0.577
40 0.698 0.642 0.839
50 0.872 0.766 1.191
60 1.047 0.866 1.732
70 1.221 0.939 2.747
80 1.396 0.984 5.671
SELECT d1
,SMALLINT(d1)
,SMALLINT('+123')
,SMALLINT('-123')
,SMALLINT(' 123 ')
FROM
scalar;
ANSWER
==================================
D1
2
3
4
5
----- ------ ------ ------ ------2.4
-2
123
-123
123
0.0
0
123
-123
123
1.8
1
123
-123
123
Figure 409, SMALLINT function examples
SELECT
FROM
WHERE
AND
AND
a.name
,SOUNDEX(a.name)
,b.name
,SOUNDEX(b.name)
,DIFFERENCE
(a.name,b.name)
staff a
,staff b
a.id = 10
b.id > 150
b.id < 250
AS
AS
AS
AS
n1
s1
n2
s2
AS df
ANSWER
==============================
N1
S1
N2
S2
DF
------- ---- --------- ---- -Sanders S536 Sneider
S536 4
Sanders S536 Smith
S530 3
Sanders S536 Lundquist L532 2
Sanders S536 Daniels
D542 1
Sanders S536 Molinare M456 1
Sanders S536 Scoutten S350 1
Sanders S536 Abrahams A165 0
ORDER BY df DESC
,n2 ASC;
Figure 410, SOUNDEX function example
WITH temp1(n1) AS
(VALUES (1),(2),(3))
SELECT n1
,SPACE(n1)
AS s1
,LENGTH(SPACE(n1)) AS s2
,SPACE(n1) || 'X' AS s3
FROM
temp1;
Figure 411, SPACE function examples
K652
L000
0
0
ANSWER
==================
N1 S1
S2 S3
-- ---- -- ---1
1
X
2
2
X
3
3
X
SELECT
*
FROM
TABLE(SQLCACHE_SNAPSHOT()) SS
WHERE
SS.NUM_EXECUTIONS <> 0;
Figure 413, SQLCACHE_SNAPSHOT function example
SELECT
ORDINAL
,CHAR(PARMNAME,18)
,TYPENAME
,LENGTH
AS COLNO
AS COLNAME
AS COLTYPE
,SCALE
FROM
SYSCAT.FUNCPARMS
WHERE
FUNCSCHEMA = 'SYSFUN'
AND
FUNCNAME
= 'SQLCACHE_SNAPSHOT'
ORDER BY COLNO;
Figure 414, List columns returned by SQLCACHE_SNAPSHOT
WITH temp1(n1) AS
(VALUES (0.5),(0.0)
,(1.0),(2.0))
SELECT DEC(n1,4,3)
AS n1
,DEC(SQRT(n1),4,3) AS s1
FROM
temp1;
ANSWER
============
N1
S1
----- ----0.500 0.707
0.000 0.000
1.000 1.000
2.000 1.414
FROM
temp1;
Figure 418, SUBSTR function - avoid error using CASE (see previous)
SELECT name
,LENGTH(name)
,SUBSTR(name,5)
,LENGTH(SUBSTR(name,5))
,SUBSTR(name,5,3)
,LENGTH(SUBSTR(name,5,3))
FROM
staff
WHERE id < 60;
ANSWER
===========================
NAME
LEN S1
L1 S2 L2
-------- --- ---- -- --- -Sanders
7 ers
3 ers 3
Pernal
6 al
2 al
3
Marenghi
8 nghi 4 ngh 3
O'Brien
7 ien
3 ien 3
Hanes
5 s
1 s
3
Figure 419, SUBSTR function - fixed length output if third parm. used
AS
AS
AS
AS
AS
len
s1
l1
s2
l2
SELECT
a.id
ANSWER
,a.dept
=========================
,a.salary
ID DEPT SALARY
DEPTSAL
,b.deptsal
-- ---- -------- -------FROM
staff a
10 20
18357.50 64286.10
,TABLE
20 20
18171.25 64286.10
(SELECT
b.dept
30 38
17506.75 77285.55
,SUM(b.salary) AS deptsal
FROM
staff b
WHERE
b.dept = a.dept
GROUP BY b.dept
)AS b
WHERE
a.id
< 40
ORDER BY a.id;
Figure 420, Full-select with external table reference
ANSWER
=======================
TABSCHEMA TABNAME CARD
--------- -------- ---graeme
employee
-1
SELECT tabschema
,tabname
,card
FROM
syscat.tables
WHERE tabname
= TABLE_NAME('emp2','graeme');
Figure 421, TABLE_NAME function example
ANSWER
===========================
TAB_SCH TAB_NME
-------- -----------------graeme
fred1
graeme
xxxxx
SELECT TIMESTAMP('1997-01-11-22.44.55.000000')
,TIMESTAMP('1997-01-11-22.44.55.000')
,TIMESTAMP('1997-01-11-22.44.55')
,TIMESTAMP('19970111224455')
,TIMESTAMP('1997-01-11','22.44.55')
FROM
staff
WHERE id = 10;
Figure 423, TIMESTAMP function examples
SELECT tm1
,TIMESTAMP_ISO(tm1)
FROM
scalar;
ANSWER
===================================
TM1
2
-------- -------------------------23:58:58 2000-09-01-23.58.58.000000
15:15:15 2000-09-01-15.15.15.000000
00:00:00 2000-09-01-00.00.00.000000
Figure 425, TIMESTAMP_ISO function example
WITH
temp1 (ts1,ts2) AS
(VALUES ('1996-03-01-00.00.01','1995-03-01-00.00.00')
,('1996-03-01-00.00.00','1995-03-01-00.00.01')),
temp2 (ts1,ts2) AS
(SELECT TIMESTAMP(ts1)
,TIMESTAMP(ts2)
FROM
temp1),
temp3 (ts1,ts2,df) AS
(SELECT ts1
,ts2
,CHAR(TS1 - TS2) AS df
ANSWER
FROM
temp2)
=============================
SELECT df
DF
DIF DYS
,TIMESTAMPDIFF(16,df) AS dif
--------------------- --- --,DAYS(ts1) - DAYS(ts2) AS dys
00010000000001.000000 365 366
FROM
temp3;
00001130235959.000000 360 366
Figure 426, TIMESTAMPDIFF function example
SELECT 'abcd'
,TRANSLATE('abcd')
,TRANSLATE('abcd','','a')
,TRANSLATE('abcd','A','A')
,TRANSLATE('abcd','A','a')
,TRANSLATE('abcd','A','ab')
,TRANSLATE('abcd','A','ab',' ')
,TRANSLATE('abcd','A','ab','z')
,TRANSLATE('abcd','AB','a')
FROM
staff
WHERE id = 10;
Figure 429, TRANSLATE function examples
==>
==>
==>
ANS.
====
abcd
ABCD
bcd
abcd
Abcd
A cd
A cd
Azcd
Abcd
NOTES
=================
No change
Make upper case
'a'=>' '
'A'=>'A'
'a'=>'A'
'a'=>'A','b'=>' '
'a'=>'A','b'=>' '
'a'=>'A','b'=>'z'
'a'=>'A'
SELECT c1
,REPLACE(c1,'AB','XY')
,REPLACE(c1,'BA','XY')
,TRANSLATE(c1,'XY','AB')
,TRANSLATE(c1,'XY','BA')
FROM
scalar
WHERE c1 = 'ABCD';
Figure 430, REPLACE vs. TRANSLATE
==>
==>
==>
ANSWER
======
ABCD
XYCD
ABCD
XYCD
YXCD
ANSWER
===============================================
D1
POS2
POS1
ZERO
NEG1
NEG2
------- ------- ------- ------- ------- ------123.400 123.400 123.400 123.000 120.000 100.000
23.450 23.440 23.400 23.000 20.000
0.000
3.456
3.450
3.400
3.000
0.000
0.000
0.056
0.050
0.000
0.000
0.000
0.000
WITH temp1(d1) AS
(VALUES (123.400)
,( 23.450)
,( 3.456)
,(
.056))
SELECT d1
,DEC(TRUNC(d1,+2),6,3) AS pos2
,DEC(TRUNC(d1,+1),6,3) AS pos1
,DEC(TRUNC(d1,+0),6,3) AS zero
,DEC(TRUNC(d1,-1),6,3) AS neg1
,DEC(TRUNC(d1,-2),6,3) AS neg2
FROM
temp1
ORDER BY 1 DESC;
Figure 431, TRUNCATE function examples
SELECT name
,LCASE(name) AS lname
,UCASE(name) AS uname
FROM
staff
WHERE id < 30;
Figure 432, UCASE function example
SELECT c1
,LENGTH(c1)
,VARCHAR(c1)
,LENGTH(VARCHAR(c1))
,VARCHAR(c1,4)
AS
AS
AS
AS
l1
v2
l2
v3
ANSWER
=========================
NAME
LNAME
UNAME
------- ------- ------Sanders sanders SANDERS
Pernal
pernal
PERNAL
ANSWER
========================
C1
L1 V2
L2 V3
------ -- ------ -- ---ABCDEF 6 ABCDEF 6 ABCD
FROM
scalar;
ABCD
AB
6 ABCD
6 AB
6 ABCD
6 AB
SELECT
WEEK(DATE('2000-01-01')) AS
,WEEK(DATE('2000-01-02')) AS
,WEEK(DATE('2001-01-02')) AS
,WEEK(DATE('2000-12-31')) AS
,WEEK(DATE('2040-12-31')) AS
FROM
sysibm.sysdummy1;
Figure 435, WEEK function examples
w1
w2
w3
w4
w5
WITH
temp1 (n) AS
(VALUES (0)
UNION ALL
SELECT n+1
FROM
temp1
WHERE n < 10),
temp2 (dt2) AS
(SELECT DATE('1998-12-27') + y.n YEARS
+ d.n DAYS
FROM
temp1 y
,temp1 d
WHERE y.n IN (0,2))
SELECT
CHAR(dt2,ISO)
dte
,SUBSTR(DAYNAME(dt2),1,3)
dy
,WEEK(dt2)
wk
,DAYOFWEEK(dt2)
dy
,WEEK_ISO(dt2)
wi
,DAYOFWEEK_ISO(dt2)
di
FROM
temp2
ORDER BY 1;
ANSWER
==================
W1 W2 W3 W4 W5
-- -- -- -- -1
2
1 54 53
ANSWER
==========================
DTE
DY WK DY WI DI
---------- --- -- -- -- -1998-12-27 Sun 53 1 52 7
1998-12-28 Mon 53 2 53 1
1998-12-29 Tue 53 3 53 2
1998-12-30 Wed 53 4 53 3
1998-12-31 Thu 53 5 53 4
1999-01-01 Fri 1 6 53 5
1999-01-02 Sat 1 7 53 6
1999-01-03 Sun 2 1 53 7
1999-01-04 Mon 2 2 1 1
1999-01-05 Tue 2 3 1 2
1999-01-06 Wed 2 4 1 3
2000-12-27 Wed 53 4 52 3
2000-12-28 Thu 53 5 52 4
2000-12-29 Fri 53 6 52 5
2000-12-30 Sat 53 7 52 6
2000-12-31 Sun 54 1 52 7
2001-01-01 Mon 1 2 1 1
2001-01-02
2001-01-03
2001-01-04
2001-01-05
2001-01-06
SELECT dt1
,YEAR(dt1) AS yr
,WEEK(dt1) AS wk
FROM
scalar;
SELECT
id
,salary
,"+"(salary)
AS s2
,"+"(salary,id) AS s3
FROM
staff
WHERE
id < 40
ORDER BY id;
Figure 438, PLUS function examples
Tue
Wed
Thu
Fri
Sat
1
1
1
1
1
3
4
5
6
7
1
1
1
1
1
2
3
4
5
6
ANSWER
======================
DT1
YR
WK
---------- ---- ---1996-04-22 1996
17
1996-08-15 1996
33
0001-01-01
1
1
ANSWER
=============================
ID SALARY
S2
S3
-- -------- -------- -------10 18357.50 18357.50 18367.50
20 18171.25 18171.25 18191.25
30 17506.75 17506.75 17536.75
SELECT
empno
,CHAR(birthdate,ISO)
AS bdate1
,CHAR(birthdate + 1 YEAR,ISO)
AS bdate2
,CHAR("+"(birthdate,DEC(00010000,8)),ISO)
AS bdate3
,CHAR("+"(birthdate,DOUBLE(1),SMALLINT(1)),ISO) AS bdate4
FROM
employee
WHERE
empno < '000040'
ORDER BY empno;
ANSWER
==================================================
EMPNO BDATE1
BDATE2
BDATE3
BDATE4
------ ---------- ---------- ---------- ---------000010 1933-08-24 1934-08-24 1934-08-24 1934-08-24
000020 1948-02-02 1949-02-02 1949-02-02 1949-02-02
000030 1941-05-11 1942-05-11 1942-05-11 1942-05-11
Figure 439, Adding one year to date value
SELECT
id
,salary
ANSWER
==============================
,"-"(salary)
AS s2
,"-"(salary,id) AS s3
FROM
staff
WHERE
id < 40
ORDER BY id;
Figure 440, MINUS function examples
id
,salary
,salary * id
AS s2
,"*"(salary,id) AS s3
FROM
staff
WHERE
id < 40
ORDER BY id;
Figure 441, MULTIPLY function examples
ID
-10
20
30
SALARY
-------18357.50
18171.25
17506.75
S2
---------18357.50
-18171.25
-17506.75
S3
-------18347.50
18151.25
17476.75
SELECT
ANSWER
===============================
ID SALARY
S2
S3
-- -------- --------- --------10 18357.50 183575.00 183575.00
20 18171.25 363425.00 363425.00
30 17506.75 525202.50 525202.50
SELECT
ANSWER
=============================
ID SALARY
S2
S3
-- -------- -------- -------10 18357.50 1835.750 1835.750
20 18171.25 908.562 908.562
30 17506.75 583.558 583.558
SELECT
ANSWER
===========================
ID N1
N2
N3
N4
--- ----- ----- ----- ----110 NganZ NganZ NganZ NganZ
210 LuZ
LuZ
LuZ
LuZ
270 LeaZ LeaZ LeaZ LeaZ
SELECT
ANSWER
====================
DEPT NAME
COMM
---- ------- ------15 Hanes
15 Rothman 1152.00
20 James
128.20
20 Pernal
612.45
id
,salary
,salary / id
AS s2
,"/"(salary,id) AS s3
FROM
staff
WHERE
id < 40
ORDER BY id;
Figure 442, DIVIDE function examples
id
,name || 'Z'
AS n1
,name CONCAT 'Z' AS n2
,"||"(name,'Z')
As n3
,CONCAT(name,'Z') As n4
FROM
staff
WHERE
LENGTH(name) < 5
ORDER BY id;
Figure 443, CONCAT function examples
dept
,name
,comm
FROM
staff
WHERE
dept < 30
AND
id
< 100
ORDER BY dept
,name;
20 Sanders
15Hanes
15Rothman01152.00
20James00128.20
20Pernal00612.45
20Sanders
Figure 445, XML version of above data
15
1501152.00
2000128.20
2000612.45
20
Figure 446, Made name an attribute of employee
SELECT
id
,XMLSERIALIZE(CONTENT
XMLELEMENT(NAME "Dept", dept)
AS CHAR(30)) AS xmldata
FROM
staff
WHERE
id BETWEEN 20 AND 30
ORDER BY id;
Figure 448, XMLSERIALIZE function example
ANSWER
==================
ID XMLDATA
-- --------------20 20
30 38
SELECT
dept AS dp
,XMLSERIALIZE(CONTENT
XMLAGG(
XMLELEMENT(NAME "Nm",
ORDER BY id)
AS CHAR(40)) AS xmldata
FROM
staff
WHERE
dept < 30
AND
id
< 80
GROUP BY dept
ORDER BY dept;
Figure 451, XMLAGG function example
SELECT
FROM
WHERE
AND
name)
ANSWER
==================================
DP XMLDATA
-- ------------------------------15 HanesRothman
20 SandersPernal
XMLSERIALIZE(CONTENT
XMLAGG(
XMLELEMENT(NAME "Nm", name)
ORDER BY name)
AS CHAR(80)) AS xmldata
staff
dept < 30
id
< 80;
XMLDATA
-----------------------------------------------------------HanesPernalRothmanSanders
Figure 452, XMLAGG function example
SELECT
id
,XMLSERIALIZE(CONTENT
XMLCONCAT(
XMLELEMENT(NAME "dp", dept)
,XMLELEMENT(NAME "nm", name)
)
AS CHAR(40)) AS xmldata
ANSWER
FROM
staff
==============================
WHERE
dept < 30
ID XMLDATA
AND
id
< 70
-- --------------------------ORDER BY id;
10 20Sanders
20 20Pernal
50 15Hanes
Figure 454, XMLCONCAT function example
SELECT
XMLSERIALIZE(CONTENT
XMLELEMENT(NAME "staff"
,XMLELEMENT(NAME "nm", name)
,XMLELEMENT(NAME "sc", salary, '+', comm)
)
AS CHAR(90)) AS xmldata
FROM
staff
WHERE
dept < 30
AND
id
< 60
ORDER BY id;
ANSWER
========================================================
Sanders18357.50+
Pernal18171.25+00612.45
Figure 456, XMLELEMENT function example
SELECT
XMLSERIALIZE(CONTENT
XMLELEMENT(NAME "Emp",
XMLATTRIBUTES(name AS "Nm", dept)
)
AS VARCHAR(100)) AS xmldata
FROM
staff
ANSWER
WHERE
dept < 30
==================================
AND
id
< 60
ORDER BY dept
,name;
Figure 458, XMLATTRIBUTES function example
SELECT
XMLSERIALIZE(CONTENT
XMLFOREST(name AS "Nm", dept AS "dp", comm)
AS VARCHAR(100)) AS xmldata
FROM
staff
WHERE
id IN (10,20)
ORDER BY id DESC;
ANSWER
===============================================
Pernal2000612.45
Sanders20
Figure 460, XMLFOREST function example
SELECT
XMLSERIALIZE(CONTENT
XMLFOREST(
XMLNAMESPACES(DEFAULT 'http:\t1.com'
,
'http:\t2.com' AS "t2"
,
'http:\t3.com' AS "t3")
,name AS "nm", salary AS "sal")
AS VARCHAR(300)) AS xmldata
FROM
staff
WHERE
id = 20;
ANSWER (line breaks/indentation added)
===========================================
Pernal
18171.25
Figure 462, XMLNAMESPACES function example
SELECT
dept
,name
,comm
FROM
staff
WHERE
dept < 30
AND
id
< 100
ORDER BY dept
,name;
Figure 463, Sample query - returns raw data
SELECT
XMLSERIALIZE(CONTENT
XMLELEMENT(NAME "Emp",
XMLELEMENT(NAME "Dept", dept),
XMLELEMENT(NAME "Name", name),
ANSWER
====================
DEPT NAME
COMM
---- ------- ------15 Hanes
15 Rothman 1152.00
20 James
128.20
20 Pernal
612.45
20 Sanders
-
SELECT
XMLSERIALIZE(CONTENT
XMLELEMENT(NAME "Emp",
XMLATTRIBUTES(name AS "Name"),
XMLELEMENT(NAME "Dept", dept),
XMLELEMENT(NAME "Comm", comm)
)
AS VARCHAR(100))
FROM
staff
WHERE
dept < 30
AND
id
< 100
ORDER BY dept
,name;
ANSWER
==============================================================
15
1501152.00
2000128.20
2000612.45
20
Figure 465, Sample query - returns XML data + attribute
SELECT
XMLSERIALIZE(CONTENT
XMLELEMENT(NAME "Data",
XMLELEMENT(NAME "Chr1",
XMLELEMENT(NAME "Chr2",
XMLELEMENT(NAME "VChr",
XMLELEMENT(NAME "Dec1",
XMLELEMENT(NAME "Dec2",
XMLELEMENT(NAME "Flt1",
XMLELEMENT(NAME "Int1",
XMLELEMENT(NAME "Int2",
XMLELEMENT(NAME "Time",
XMLELEMENT(NAME "Date",
XMLELEMENT(NAME "Ts" ,
)
AS VARCHAR(300)) AS xmldata
CHAR
(c1,3)),
CHAR
(c1,5)),
VARCHAR(c1,5)),
DECIMAL(n1,7,2)),
DECIMAL(n2,9,1)),
FLOAT (n2)),
INTEGER(n1)),
INTEGER(n2)),
TIME
(t1)),
DATE
(t1)),
TIMESTAMP(t1))
FROM
(SELECT
FROM
WHERE
)AS xxx;
'ABC'
,1234.56
,1234567
,TIMESTAMP('2004-09-14-22.33.44.123456')
staff
id = 10
AS
AS
AS
AS
c1
n1
n2
t1
ANSWER
WITH temp1 (indata) AS
===========================
(VALUES ('<txt
,('"txt'))
txt>
txt>
SELECT
indata
&txt
&txt
,XMLSERIALIZE(CONTENT
"txt
"txt
XMLELEMENT(NAME "Out", indata))
AS CHAR(50)) AS outdata
FROM
temp1;
Figure 467, Convert XML input strings
SELECT
XMLSERIALIZE(CONTENT
XMLELEMENT(NAME "Emp", dept, name, comm)
AS CHAR(50)) AS outdata
FROM
staff
ANSWER
WHERE
dept < 30
===========================
AND
id
< 100
15Hanes
ORDER BY dept
15Rothman01152.0020James00128.20
20Pernal00612.45
20Sanders
Figure 468, Concatenation done in XML function
SELECT
XMLSERIALIZE(CONTENT
XMLELEMENT(NAME "Emp", CHAR(dept) || name || CHAR(comm))
AS CHAR(50)) AS outdata
staff
dept < 30
id
< 100
dept
,name;
FROM
WHERE
AND
ORDER BY
ANSWER
=================================
15
20
20
Rothman01152.00
James00128.20
Pernal00612.45
SELECT
XMLSERIALIZE(CONTENT
XMLELEMENT(NAME "Emp",
XMLATTRIBUTES(name), dept, comm)
)
AS CHAR(100)) AS xmldata
FROM
staff
WHERE
dept < 30
ANSWER
AND
id
< 100
====================================
ORDER BY dept
15
,name;
1501152.00
2000128.20
2000612.45
20
Figure 470, One element, one attribute, two data-items
SELECT
XMLSERIALIZE(CONTENT
XMLELEMENT(NAME "Emp",
XMLATTRIBUTES(name, dept, comm)
)
AS VARCHAR(100)) AS xmldata
FROM
staff
WHERE
dept < 30
AND
id
< 100
ORDER BY dept
ANSWER
,name;
====================================================
SELECT
XMLSERIALIZE(CONTENT
XMLELEMENT(NAME "Emp",
XMLATTRIBUTES(name AS "Nm", dept AS "Dpt", comm)
)
AS VARCHAR(100)) AS xmldata
FROM
WHERE
AND
ORDER BY
staff
dept < 30
id
< 100
dept
,name;
ANSWER
=================================================
SELECT
XMLSERIALIZE(CONTENT
XMLELEMENT(NAME "Dpt",
XMLATTRIBUTES(dept),
XMLAGG(
XMLELEMENT(NAME "Emp",
XMLELEMENT(NAME "Nm", name),
XMLELEMENT(NAME "Cm", comm))
ORDER BY id)
)
AS VARCHAR(300)) AS xmldata
FROM
staff
WHERE
dept < 30
AND
id
< 100
GROUP BY dept;
ANSWER (line-breaks/indentation added)
===============================================
Hanes
Rothman01152.00
Sanders
Pernal00612.45
James00128.20
Figure 473, XMLAGG function example
SELECT
FROM
WHERE
ORDER BY
38
O'Brien
00846.55
Figure 477, REC2XML function example
SELECT
id
,DIGITS(id)
,digi_int(id)
FROM
staff
WHERE
id < 40
ORDER BY id;
AS ID
AS I2
AS I3
ANSWER
==============
ID I2
I3
-- ----- ----10 00010 00010
20 00020 00020
30 00030 00030
SELECT
id
,digi_int(INT(id))
FROM
staff
WHERE
id < 50;
Figure 481, Using sourced function - fails
ANSWER
=======
NOT NULL
NOT NULL);
SELECT
id
,balance * 10
FROM
customers
ORDER BY id;
Figure 483, Do multiply - fails
ANSWER
==========
ID balance
-- ------1 111.11
2 222.22
ANSWER
=======
SELECT
id
,balance * 10 AS newbal
FROM
customers
ORDER BY id;
ANSWER
==========
ID NEWBAL
-- ------1 1111.10
2 2222.20
SELECT
id
,"*"(balance,10) AS newbal
FROM
customers
ORDER BY id;
Figure 486, Do multiply - works
ANSWER
==========
ID NEWBAL
-- ------1 1111.10
2 2222.20
id
AS id
,returns_zero() AS zz
FROM
staff
WHERE
id = 10;
Figure 489, Simple function usage
ANSWER
======
ID ZZ
-- -10 0
id
AS id
,calc(SMALLINT(id)) AS c1
,calc(INTEGER (id)) AS C2
FROM
staff
WHERE
id < 30
ORDER BY id;
DROP FUNCTION calc(SMALLINT);
DROP FUNCTION calc(INTEGER);
Figure 490, Two functions with same name
ANSWER
==========
ID C1 C2
-- --- --10 100 50
20 200 100
id
AS id
,rnd(1) AS RND
FROM
staff
WHERE
id < 40
ORDER BY id;
Figure 491, Not deterministic function
id
AS id
,get_sal(id) AS salary
FROM
staff
WHERE
id < 40
ORDER BY id;
Figure 492, Function using query
ANSWER
======
ID RND
-- --10 37
20
8
30 42
ANSWER
===========
ID SALARY
-- -------10 18357.50
20 18171.25
30 17506.75
id
,salary
AS id
AS SAL1
ANSWER
====================
ID SAL1
SAL2
,max_sal(id) AS SAL2
-FROM
staff
10
WHERE
id < 40
20
ORDER BY id;
30
Figure 493, Function using common table expression
-------18357.50
18171.25
17506.75
-------22959.20
18357.50
19260.25
--#SET DELIMITER !
IMPORTANT
============
This example
uses an "!"
as the stmt
delimiter.
--#SET DELIMITER !
CREATE FUNCTION check_len(instr VARCHAR(50))
RETURNS SMALLINT
BEGIN ATOMIC
IF instr IS NULL THEN
RETURN NULL;
END IF;
IF length(instr) < 6 THEN
SIGNAL SQLSTATE '75001'
IMPORTANT
============
This example
uses an "!"
as the stmt
delimiter.
id
AS id
,name
AS name1
,check_len(name) AS name2
FROM
staff
WHERE
id < 60
ORDER BY id!
Figure 496, Function with error checking logic
ANSWER
=================
ID NAME1
NAME2
-- -------- ----10 Sanders
7
20 Pernal
-1
30 Marenghi
8
40 O'Brien
7
ANSWER
==============
ID NAME
YR
-- -------- -10 Sanders
7
20 Pernal
8
30 Marenghi 5
ANSWER
==============
ID NNN
YY
-- -------- -30 Marenghi 5
ANSWER
========
KY DAT
-- ----1 00001
2 00002
3 00003
empno
,CHAR(hiredate,ISO)
AS h_date
,JULIAN_OUT(hiredate) AS j_date
FROM
employee
WHERE
empno < '000050'
ORDER BY empno;
Figure 502, Convert Date into Julian Date
SELECT
FROM
WHERE
ANSWER
=========================
EMPNO H_DATE
J_DATE
------ ---------- ------000010 1965-01-01 1965001
000020 1973-10-10 1973283
000030 1975-04-05 1975095
CHAR(7))
- 1) YEARS
- 1) DAYS;
into Date
empno
,hiredate
employee
YEAR(hiredate) = YEAR(CURRENT DATE) - 1;
SELECT
empno
,hiredate
FROM
employee
WHERE
YEAR_MONTH(hiredate) = YEAR_MONTH(CURRENT DATE) - 1;
Figure 506, Select rows where hire-date = prior month
WITH
ANSWER
temp1 (num,dt) AS
==================================
(VALUES (1
DATE
DAY WK IS SUN_WK MON_WK
,DATE('2004-12-29'))
---------- --- -- -- ------ -----UNION ALL
2004-12-29 Wed 53 53 104563 104563
SELECT num + 1
2004-12-30 Thu 53 53 104563 104563
,dt + 1 DAY
2004-12-31 Fri 53 53 104563 104563
FROM
temp1
2005-01-01 Sat 1 53 104563 104563
WHERE
num < 15
2005-01-02 Sun 2 53 104564 104563
),
2005-01-03 Mon 2 1 104564 104564
temp2 (dt,dy) AS
2005-01-04 Tue 2 1 104564 104564
(SELECT dt
2005-01-05 Wed 2 1 104564 104564
,SUBSTR(DAYNAME(dt),1,3) 2005-01-06 Thu 2 1 104564 104564
FROM
temp1
2005-01-07 Fri 2 1 104564 104564
)
2005-01-08 Sat 2 1 104564 104564
SELECT
CHAR(dt,ISO)
AS date
2005-01-09 Sun 3 1 104565 104564
,dy
AS day
2005-01-10 Mon 3 2 104565 104565
,WEEK(dt)
AS wk
2005-01-11 Tue 3 2 104565 104565
,WEEK_ISO(dt)
AS is
2005-01-12 Wed 3 2 104565 104565
,sunday_week(dt) AS sun_wk
,monday_week(dt) AS mon_wk
FROM
temp2
ORDER BY 1;
Figure 509, Use week-number functions
FROM
WHERE
temp1
num < max_num
)
SELECT num
FROM
temp1;
Figure 510, Create num-list function
SELECT
FROM
*
TABLE(NumList(-1)) AS xxx;
ANSWERS
=======
0
SELECT
FROM
*
TABLE(NumList(+0)) AS xxx;
SELECT
FROM
*
TABLE(NumList(+3)) AS xxx;
0
1
2
3
SELECT
*
FROM
TABLE(NumList(CAST(NULL AS INTEGER))) AS xxx;
Figure 511, Using num-list function
SELECT
actno
ANSWER
,emstdate
=================================
,emendate
ACTNO EMSTDATE
EMENDATE
#DAYS
,DAYS(emendate) ----- ---------- ---------- ----DAYS(emstdate) AS #days
70 1982-06-15 1982-07-01
16
FROM
emp_act act
80 1982-03-01 1982-04-15
45
WHERE
empno
= '000260'
AND
projno = 'AD3113'
AND
actno
< 100
AND
emptime = 0.5
ORDER BY actno;
Figure 512, Select activity start & end date
SELECT
FROM
actno
,#days
,num
,emstdate + num DAYS AS new_date
(SELECT
actno
,emstdate
,emendate
,DAYS(emendate) DAYS(emstdate) AS #days
FROM
emp_act act
WHERE
empno
= '000260'
AND
projno = 'AD3113'
ANSWER
==========================
ACTNO #DAYS NUM NEW_DATE
----- ----- --- ---------70
16
0 1982-06-15
70
16
1 1982-06-16
70
16
2 1982-06-17
70
16
3 1982-06-18
70
16
4 1982-06-19
70
16
5 1982-06-20
70
16
6 1982-06-21
70
16
7 1982-06-22
AND
actno
< 100
70
16
8 1982-06-23
AND
emptime = 0.5
70
16
9 1982-06-24
)AS aaa
70
16 10 1982-06-25
,TABLE(NumList(#days)) AS ttt
etc...
ORDER BY actno
,num;
Figure 513, Generate one row per date between start & end dates (1 of 2)
SELECT
actno
,#days
,num
ACTNO #DAYS NUM NEW_DATE
,emstdate + num DAYS AS new_date
----- ----- --- ---------FROM
(SELECT
actno
70
16
0 1982-06-15
,emstdate
70
16
1 1982-06-16
,emendate
70
16
2 1982-06-17
,DAYS(emendate) 70
16
3 1982-06-18
DAYS(emstdate) AS #days
70
16
4 1982-06-19
FROM
emp_act act
70
16
5 1982-06-20
WHERE
empno
= '000260'
70
16
6 1982-06-21
AND
projno = 'AD3113'
70
16
7 1982-06-22
AND
actno
< 100
70
16
8 1982-06-23
AND
emptime = 0.5
70
16
9 1982-06-24
)AS aaa
70
16 10 1982-06-25
LEFT OUTER JOIN
etc...
TABLE(NumList(#days)) AS ttt
ON
1 = 1
ORDER BY actno
,num;
Figure 514, Generate one row per date between start & end dates (2 of 2)
ELSE 0
END;
Figure 516, Check if input value is numeric
ANSWER
==========
INDATA C N
------ - ABC
1 0
123
0 1
3.4
0 0
-44
0 0
A1
0 0
1 1
WHEN
TRANSLATE(inval,' ','-.01234567890')
= ' '
- 1
- 1
- 1
- 1
- 1
AND LOCATE('-',LTRIM(inval))
= 1
AND LENGTH(REPLACE(inval,'-',''))
= LENGTH(inval) - 1
AND LENGTH(REPLACE(inval,'.',''))
= LENGTH(inval) - 1
THEN 'DEC-'
ELSE '
'
END;
Figure 519, Check if input value is numeric - part 2 of 2
ANSWER
==================
INDATA TYPE NUMBER
------ ---- -----ABC
123
INT 123.00
3.4
DEC
3.40
-44
INT- -44.00
+11
INT+ 11.00
-112+
+.1
DEC+
0.10
-0.
DEC0.00
1 1
.
-
SELECT
col1
,col2
FROM
seq_data
ORDER BY col1 ASC
,col2;
ANSWER
=========
COL1 COL2
---- ---ab
xy
ac
XY
Ab
12
SEQ_DATA
+---------+
|COL1|COL2|
|----+----|
|ab |xy |
|AB |xy |
|ac |XY |
AB
AB
Figure 523, Simple ORDER BY
SELECT
col1
,col2
FROM
seq_data
ORDER BY TRANSLATE(col1) ASC
,TRANSLATE(col2) ASC
SELECT
col2
FROM
seq_data
ORDER BY col1
,col2;
SELECT
col1
,col2
FROM
seq_data
ORDER BY SUBSTR(col1,2) DESC
,col2
,1;
SELECT
FROM
col1
,HEX(col1) AS hex1
,col2
,HEX(col2) AS hex2
seq_data
xy
XY
|AB |XY |
|Ab |12 |
+---------+
ANSWER
=========
COL1 COL2
---- ---Ab
12
ab
xy
AB
XY
AB
xy
ac
XY
ANSWER
======
COL2
---xy
XY
12
xy
XY
ANSWER
=========
COL1 COL2
---- ---ac
XY
AB
xy
AB
XY
Ab
12
ab
xy
ANSWER
===================
COL1 HEX1 COL2 HEX2
---- ---- ---- ---AB
4142 XY
5859
ORDER BY HEX(col1)
,HEX(col2)
AB
Ab
ab
ac
4142
4162
6162
6163
xy
12
xy
XY
7879
3132
7879
5859
SELECT
FROM
col1
(SELECT
FROM
ORDER BY
) AS xxx
ORDER BY ORDER OF
col1
seq_data
col2
xxx;
SELECT
FROM
*
(SELECT
FROM
*
(SELECT
*
FROM
seq_data
ORDER BY col2
)AS xxx
ORDER BY ORDER OF xxx
,SUBSTR(col1,2)
)AS yyy
ORDER BY ORDER OF yyy
,col1;
Figure 529, Multiple nested ORDER BY statements
SELECT
empno
,projno AS prj
,actno AS act
,ROW_NUMBER() OVER() AS r#
FROM
FINAL TABLE
(INSERT INTO emp_act (empno, projno, actno)
VALUES ('400000','ZZZ',999)
,('400000','VVV',111))
ORDER BY INPUT SEQUENCE;
Figure 530, ORDER BY insert input sequence
ANSWER
======
COL1
---Ab
ab
AB
ac
AB
SEQ_DATA
+---------+
|COL1|COL2|
|----+----|
|ab |xy |
|AB |xy |
|ac |XY |
|AB |XY |
|Ab |12 |
+---------+
ANSWER
=========
COL1 COL2
---- ---Ab
12
ab
xy
AB
xy
AB
XY
ac
XY
ANSWER
=================
EMPNO PRJ ACT R#
------ --- --- -400000 ZZZ 999 1
400000 VVV 111 2
GROUP
UNION
GROUP
UNION
GROUP
UNION
GROUP
SELECT
*
FROM
employee_view
ORDER BY 1,2,3,4;
AS
AS
AS
AS
d1
dept
sex
salary
ANSWER
==================
D1 DEPT SEX SALARY
-- ---- --- -----A A00 F
52750
A A00 M
29250
A A00 M
46500
B B01 M
41250
C C01 F
23800
C C01 F
28420
C C01 F
38250
D D11 F
21340
D D11 F
22250
D D11 F
29840
D D11 M
18270
D D11 M
20450
D D11 M
24680
D D11 M
25280
D D11 M
27740
D11
32250
SELECT
ANSWER
========================
D1 DEPT SEX SALARY #ROWS
-- ---- --- ------ ----A A00 F
52750
1
A A00 M
75750
2
B B01 M
41250
1
C C01 F
90470
3
D D11 F
73430
3
D D11 M
148670
6
SELECT
ANSWER
================
SEX SALARY #ROWS
--- ------ ----F
52750
1
F
90470
3
F
73430
3
M
75750
2
M
41250
1
M
148670
6
sex
,SUM(salary)
AS salary
,SMALLINT(COUNT(*)) AS #rows
FROM
employee_view
WHERE
sex IN ('F','M')
GROUP BY dept
,sex
ORDER BY sex;
Figure 536, GROUP BY on non-displayed field
SELECT
SUM(salary)
AS salary
,SMALLINT(COUNT(*)) AS #rows
FROM
employee_view
WHERE
d1 <> 'X'
GROUP BY SUBSTR(dept,3,1)
HAVING
COUNT(*) <> 99;
Figure 537, GROUP BY on derived field, not shown
ANSWER
============
SALARY #ROWS
------ ----128500
3
353820
13
SELECT
ANSWER
==================
WPART SALARY #ROWS
----- ------ ----1
353820
13
0
128500
3
SUBSTR(dept,3,1)
AS wpart
,SUM(salary)
AS salary
,SMALLINT(COUNT(*)) AS #rows
FROM
employee_view
GROUP BY SUBSTR(dept,3,1)
ORDER BY wpart DESC;
Figure 538, GROUP BY on derived field, shown
is equivalent to
GROUP BY A
,B
,C
is equivalent to
GROUP
UNION
GROUP
UNION
GROUP
is equivalent to
GROUP BY A
UNION ALL
GROUP BY B
,BY C
BY A
ALL
BY B
ALL
BY C
is equivalent to
GROUP BY A
,B
,C
is equivalent to
GROUP BY A
,B
,C
is equivalent to
GROUP BY A
,B
UNION ALL
GROUP BY A
,C
GROUP BY A
,GROUPING SETS ((B,C))
is equivalent to
GROUP BY A
,B
,C
Figure 541, Simple GROUP BY expression and GROUPING SETS combined
GROUP BY A
,B
,GROUPING SETS ((B,C))
is equivalent to
GROUP BY A
,B
,C
GROUP BY A
,B
is equivalent to
GROUP BY A
,B
,C
UNION ALL
GROUP BY A
,B
GROUP BY A
,B
,C
,GROUPING SETS (B,C)
is equivalent to
GROUP BY A
,B
,C
UNION ALL
GROUP BY A
,B
,C
Figure 542, Mixing simple GROUP BY expressions and GROUPING SETS
is equivalent to
GROUP BY A
,B
,C
UNION ALL
GROUP BY A
,B
UNION ALL
GROUP BY C
is equivalent to
GROUP BY A
UNION ALL
GROUP BY B
,C
UNION ALL
GROUP BY A
UNION ALL
GROUP BY A
UNION ALL
GROUP BY C
GROUP BY A
,B
,C
UNION ALL
GROUP BY A
,B
is equivalent to
UNION ALL
GROUP BY A
UNION ALL
ROLLUP(A,B,C)
grand-totl
Figure 544, GROUPING SET with multiple components, using grand-total
is equivalent to
is equivalent to
GROUP BY A
,(A,B)
,(A,C)
,(B,C)
,(A)
,(B)
,(C)
,())
,B
,C
UNION ALL
GROUP BY A
,B
UNION ALL
GROUP BY A
,C
UNION ALL
GROUP BY B
is equivalent to
,C
UNION ALL
GROUP BY A
UNION ALL
CUBE(A,B,C)
GROUP BY B
UNION ALL
GROUP BY C
UNION ALL
grand-totl
Figure 545, GROUPING SET with multiple components, using grand-total
SELECT
d1
ANSWER
,dept
==============================
,sex
D1 DEPT SEX
SAL #R DF WF SF
,SUM(salary)
AS sal
-- ---- --- ------ -- -- -- -,SMALLINT(COUNT(*)) AS #r
A A00 F
52750 1 0 0 0
,GROUPING(d1)
AS f1
A A00 M
75750 2 0 0 0
,GROUPING(dept)
AS fd
B B01 M
41250 1 0 0 0
,GROUPING(sex)
AS fs
C C01 F
90470 3 0 0 0
FROM
employee_view
D D11 F
73430 3 0 0 0
GROUP BY GROUPING SETS (d1)
D D11 M
148670 6 0 0 0
,GROUPING SETS ((dept,sex))
ORDER BY d1
,dept
,sex;
Figure 546, Multiple GROUPING SETS, making one GROUP BY
SELECT
d1
ANSWER
,dept
==============================
,sex
D1 DEPT SEX
SAL #R F1 FD FS
,SUM(salary)
AS sal
-- ---- --- ------ -- -- -- -,SMALLINT(COUNT(*)) AS #r
A
A00 128500 3 0 0 1
,GROUPING(d1)
AS f1
A
F
52750 1 0 1 0
,GROUPING(dept)
AS fd
A
M
75750 2 0 1 0
,GROUPING(sex)
AS fs
B
B01 41250 1 0 0 1
FROM
employee_view
B
M
41250 1 0 1 0
GROUP BY GROUPING SETS (d1)
C
C01 90470 3 0 0 1
,GROUPING SETS (dept,sex)
C
F
90470 3 0 1 0
ORDER BY d1
D
D11 222100 9 0 0 1
,dept
D
F
73430 3 0 1 0
,sex;
D
M
148670 6 0 1 0
Figure 547, Multiple GROUPING SETS, making two GROUP BY results
SELECT
d1
ANSWER
,dept
==============================
,sex
D1 DEPT SEX SAL
#R F1 FD FS
,SUM(salary)
AS sal
-----------------------------,SMALLINT(COUNT(*)) AS #r
A A00 F
52750 1 0 0 0
,GROUPING(d1)
AS f1
A A00 M
75750 2 0 0 0
,GROUPING(dept)
AS fd
B B01 M
41250 1 0 0 0
,GROUPING(sex)
AS fs
C C01 F
90470 3 0 0 0
FROM
employee_view
D D11 F
73430 3 0 0 0
GROUP BY d1
D D11 M
148670 6 0 0 0
,dept
,GROUPING SETS ((dept,sex))
ORDER BY d1
,dept
,sex;
Figure 548, Repeated field essentially ignored
SELECT
d1
ANSWER
,dept
==============================
,sex
D1 DEPT SEX SAL
#R F1 FD FS
,SUM(salary)
AS sal
-----------------------------,SMALLINT(COUNT(*)) AS #r
A A00 F
52750 1 0 0 0
,GROUPING(d1)
AS f1
A A00 M
75750 2 0 0 0
,GROUPING(dept)
AS fd
A A00 128500 3 0 0 1
,GROUPING(sex)
AS fs
B B01 M
41250 1 0 0 0
FROM
employee_view
B B01 41250 1 0 0 1
GROUP BY d1
C C01 F
90470 3 0 0 0
,DEPT
C C01 90470 3 0 0 1
,GROUPING SETS (dept,sex)
D D11 F
73430 3 0 0 0
ORDER BY d1
D D11 M
148670 6 0 0 0
,dept
D D11 222100 9 0 0 1
,sex;
Figure 549, Repeated field impacts query result
GROUP BY d1
,dept
,GROUPING SETS ((dept,sex))
is equivalent to
GROUP BY d1
,dept
sex
GROUP BY d1
,dept
,GROUPING SETS (dept,sex)
is equivalent to
GROUP BY d1
,dept
sex
UNION ALL
GROUP BY d1
,dept
,dept
GROUP BY ROLLUP(A,B,C)
===>
GROUP BY ROLLUP(C,B)
===>
GROUP BY ROLLUP(A)
===>
GROUP BY ROLLUP(A,(B,C))
===>
GROUP BY ROLLUP(A)
,ROLLUP(B,C)
===>
ROLLUP(A)
GROUPING SETS((A)
,())
ROLLUP(B,C)
GROUPING SETS((B,C)
,(B)
())
Figure 554, Multiplying GROUPING SETS
SELECT
dept
,SUM(salary)
AS salary
,SMALLINT(COUNT(*)) AS #rows
,GROUPING(dept)
AS fd
=
=
GROUPING SETS((A,B,C)
,(A,B)
,(A)
,(B,C)
,(B)
,(())
ANSWER
====================
DEPT SALARY #ROWS FD
---- ------ ----- --
FROM
employee_view
GROUP BY dept
ORDER BY dept;
A00
B01
C01
D11
128500
41250
90470
222100
3
1
3
9
0
0
0
0
SELECT
dept
,SUM(salary)
AS salary
,SMALLINT(COUNT(*)) AS #rows
,GROUPING(dept)
AS FD
FROM
employee_view
GROUP BY ROLLUP(dept)
ORDER BY dept;
ANSWER
====================
DEPT SALARY #ROWS FD
---- ------ ----- -A00 128500
3 0
B01
41250
1 0
C01
90470
3 0
D11 222100
9 0
482320
16 1
SELECT
dept
,SUM(salary)
AS salary
,SMALLINT(COUNT(*))
AS #rows
,GROUPING(dept)
AS fd
FROM
employee_view
GROUP BY dept
UNION ALL
SELECT
CAST(NULL AS CHAR(3)) AS dept
,SUM(salary)
AS salary
,SMALLINT(COUNT(*))
AS #rows
,CAST(1 AS INTEGER)
AS fd
FROM
employee_view
ORDER BY dept;
Figure 557, ROLLUP done the old-fashioned way
SELECT
dept
,SUM(salary)
AS salary
,SMALLINT(COUNT(*)) AS #rows
,GROUPING(dept)
AS fd
FROM
employee_view
GROUP BY dept
,ROLLUP(dept)
ORDER BY dept;
ANSWER
====================
DEPT SALARY #ROWS FD
---- ------ ----- -A00 128500
3 0
B01
41250
1 0
C01
90470
3 0
D11 222100
9 0
482320
16 1
ANSWER
====================
DEPT SALARY #ROWS FD
---- ------ ----- -A00 128500
3 0
A00 128500
3 0
B01
41250
1 0
B01
41250
1 0
C01
90470
3 0
C01
90470
3 0
D11 222100
9 0
D11 222100
9 0
Figure 558, Repeating a field in GROUP BY and ROLLUP (error)
GROUP BY dept
=> GROUP BY dept
=> GROUP BY dept
,ROLLUP(dept)
,GROUPING SETS((dept)
UNION ALL
,())
GROUP BY dept
,()
Figure 559, Repeating a field, explanation
SELECT
dept
,sex
,SUM(salary)
,SMALLINT(COUNT(*))
,GROUPING(dept)
,GROUPING(sex)
FROM
employee_view
GROUP BY dept
,ROLLUP(sex)
ORDER BY dept
,sex;
ANSWER
===========================
AS salary
DEPT SEX SALARY #ROWS FD FS
AS #rows
---- --- ------ ----- -- -AS fd
A00 F
52750
1 0 0
AS fs
A00 M
75750
2 0 0
A00 128500
3 0 1
B01 M
41250
1 0 0
B01 41250
1 0 1
C01 F
90470
3 0 0
C01 90470
3 0 1
D11 F
73430
3 0 0
D11 M
148670
6 0 0
D11 222100
9 0 1
Figure 560, GROUP BY on 1st field, ROLLUP on 2nd
SELECT
dept
,sex
,SUM(salary)
,SMALLINT(COUNT(*))
,GROUPING(dept)
,GROUPING(sex)
FROM
employee_view
GROUP BY ROLLUP(dept
,sex)
ORDER BY dept
,sex;
AS
AS
AS
AS
salary
#rows
fd
fs
ANSWER
===========================
DEPT SEX SALARY #ROWS FD FS
---- --- ------ ----- -- -A00 F
52750
1 0 0
A00 M
75750
2 0 0
A00 128500
3 0 1
B01 M
41250
1 0 0
B01 41250
1 0 1
C01 F
90470
3 0 0
C01 90470
3 0 1
D11 F
73430
3 0 0
D11 M
148670
6 0 0
D11 222100
9 0 1
482320
16 1 1
SELECT
sex
,dept
,SUM(salary)
,SMALLINT(COUNT(*))
,GROUPING(dept)
,GROUPING(sex)
AS
AS
AS
AS
salary
#rows
fd
fs
ANSWER
===========================
SEX DEPT SALARY #ROWS FD FS
--- ---- ------ ----- -- -F
A00
52750
1 0 0
F
C01
90470
3 0 0
FROM
employee_view
GROUP BY ROLLUP(sex
,dept)
ORDER BY sex
,dept;
Figure 562, ROLLUP on SEX, then DEPT
SELECT
sex
,dept
,SUM(salary)
AS salary
,SMALLINT(COUNT(*)) AS #rows
,GROUPING(dept)
AS fd
,GROUPING(sex)
AS fs
FROM
employee_view
GROUP BY GROUPING SETS ((sex, dept)
,(sex)
,())
ORDER BY sex
,dept;
Figure 563, ROLLUP on SEX, then DEPT
SELECT
sex
,dept
,SUM(salary)
,SMALLINT(COUNT(*))
,GROUPING(dept)
,GROUPING(sex)
FROM
employee_view
GROUP BY ROLLUP(sex)
,ROLLUP(dept)
ORDER BY sex
,dept;
AS
AS
AS
AS
salary
#rows
fd
fs
SELECT
dept
,sex
,SUM(salary)
AS salary
,SMALLINT(COUNT(*)) AS #rows
,GROUPING(dept)
AS fd
F
F
M
M
M
M
-
D11
A00
B01
D11
-
73430
216650
75750
41250
148670
265670
482320
3
7
2
1
6
9
16
0
1
0
0
0
1
1
0
0
0
0
0
0
1
ANSWER
===========================
SEX DEPT SALARY #ROWS FD FS
--- ---- ------ ----- -- -F
A00
52750
1 0 0
F
C01
90470
3 0 0
F
D11
73430
3 0 0
F
216650
7 1 0
M
A00
75750
2 0 0
M
B01
41250
1 0 0
M
D11 148670
6 0 0
M
265670
9 1 0
482320
16 1 1
ANSWER
===========================
SEX DEPT SALARY #ROWS FD FS
--- ---- ------ ----- -- -F
A00
52750
1 0 0
F
C01
90470
3 0 0
F
D11
73430
3 0 0
F
216650
7 1 0
M
A00
75750
2 0 0
M
B01
41250
1 0 0
M
D11 148670
6 0 0
M
265670
9 1 0
A00 128500
3 0 1
B01
41250
1 0 1
C01
90470
3 0 1
D11 222100
9 0 1
482320
16 1 1
ANSWER
===========================
DEPT SEX SALARY #ROWS FD FS
---- --- ------ ----- -- -A00 F
52750
1 0 0
,GROUPING(sex)
AS fs
FROM
employee_view
GROUP BY ROLLUP((dept,sex))
ORDER BY dept
,sex;
A00
B01
C01
D11
D11
-
M
M
F
F
M
-
75750
41250
90470
73430
148670
482320
2
1
3
3
6
16
0
0
0
0
0
1
0
0
0
0
0
1
SELECT
SUM(salary)
AS salary
,SMALLINT(COUNT(*)) AS #rows
FROM
employee_view
GROUP BY ROLLUP(sex
,dept)
HAVING
GROUPING(dept) = 1
AND
GROUPING(sex) = 1
ORDER BY salary;
Figure 566, Use HAVING to get only grand-total row
ANSWER
============
SALARY #ROWS
------ ----482320
16
SELECT
ANSWER
============
SALARY #ROWS
------ ----482320
16
SUM(salary)
AS salary
,SMALLINT(COUNT(*)) AS #rows
FROM
employee_view
GROUP BY GROUPING SETS(());
Figure 567, Use GROUPING SETS to get grand-total row
SELECT
SUM(salary)
AS salary
,SMALLINT(COUNT(*)) AS #rows
FROM
employee_view
GROUP BY ();
Figure 568, Use GROUP BY to get grand-total row
SELECT
FROM
SUM(salary)
AS salary
,SMALLINT(COUNT(*)) AS #rows
employee_view;
ANSWER
============
SALARY #ROWS
------ ----482320
16
ANSWER
============
SALARY #ROWS
------ ----482320
16
GROUP BY CUBE(A,B,C)
===>
GROUP BY CUBE(C,B)
===>
GROUP BY CUBE(A)
===>
GROUP BY CUBE(A,(B,C))
===>
GROUP BY CUBE(A,B)
,CUBE(B,C)
==>
GROUPING SETS((A,B,C),(A,B),(A,B,C),(A,B)
,(A,B,C),(A,B),(A,C),(A)
,(B,C),(B),(B,C),(B)
,(B,C),(B),(C),())
Figure 572, CUBE vs. GROUPING SETS
SELECT
d1
,dept
,sex
,INT(SUM(salary))
AS
,SMALLINT(COUNT(*)) AS
,GROUPING(d1)
AS
,GROUPING(dept)
AS
,GROUPING(sex)
AS
FROM
employee_view
GROUP BY CUBE(d1, dept, sex)
ORDER BY d1
,dept
,sex;
sal
#r
f1
fd
fs
ANSWER
==============================
D1 DEPT SEX
SAL #R F1 FD FS
-- ---- --- ------ -- -- -- -A A00 F
52750 1 0 0 0
A A00 M
75750 2 0 0 0
A A00 128500 3 0 0 1
A F
52750 1 0 1 0
A M
75750 2 0 1 0
A 128500 3 0 1 1
B B01 M
41250 1 0 0 0
B B01 41250 1 0 0 1
B M
41250 1 0 1 0
B 41250 1 0 1 1
C C01 F
90470 3 0 0 0
C C01 90470 3 0 0 1
C F
90470 3 0 1 0
C
D
D
D
D
D
D
-
D11
D11
D11
A00
A00
A00
B01
B01
C01
C01
D11
D11
D11
-
F
M
F
M
F
M
M
F
F
M
F
M
-
90470 3
73430 3
148670 6
222100 9
73430 3
148670 6
222100 9
52750 1
75750 2
128500 3
41250 1
41250 1
90470 3
90470 3
73430 3
148670 6
222100 9
216650 7
265670 9
482320 16
0
0
0
0
0
0
0
1
1
1
1
1
1
1
1
1
1
1
1
1
1
0
0
0
1
1
1
0
0
0
0
0
0
0
0
0
0
1
1
1
1
0
0
1
0
0
1
0
0
1
0
1
0
1
0
0
1
0
0
1
SELECT
d1
ANSWER
,dept
==============================
,sex
D1 DEPT SEX
SAL #R F1 FD FS
,INT(SUM(salary))
AS sal
-- ---- --- ------ -- -- -- -,SMALLINT(COUNT(*)) AS #r
A A00 F
52750 1 0 0 0
,GROUPING(d1)
AS f1
A A00 M
75750 2 0 0 0
,GROUPING(dept)
AS fd
etc... (same as prior query)
,GROUPING(sex)
AS fs
FROM
employee_view
GROUP BY GROUPING SETS ((d1, dept, sex)
,(d1,dept)
,(d1,sex)
,(dept,sex)
,(d1)
,(dept)
,(sex)
,())
ORDER BY d1
,dept
,sex;
Figure 574, CUBE expressed using multiple GROUPING SETS
SELECT
FROM
d1
,dept
,sex
,INT(SUM(salary))
,SMALLINT(COUNT(*))
,GROUPING(d1)
,GROUPING(dept)
,GROUPING(sex)
employee_VIEW
AS
AS
AS
AS
AS
sal
#r
f1
fd
fs
ANSWER
==============================
D1 DEPT SEX SAL
#R F1 FD FS
-----------------------------A A00 F
52750 1 0 0 0
A A00 M
75750 2 0 0 0
B B01 M
41250 1 0 0 0
C C01 F
90470 3 0 0 0
D D11 F
73430 3 0 0 0
D
-
D11
-
M
-
148670 6
482320 16
0
1
0
1
0
1
GROUP BY A
,B
,C
UNION ALL
GROUP BY()
SELECT
d1
AS d1
,dept
AS dpt
,sex
AS sx
,INT(SUM(salary))
AS sal
,SMALLINT(COUNT(*)) AS r
FROM
employee_VIEW
GROUP BY d1
,dept
,sex
ORDER BY 1,2,3;
Figure 577, Basic GROUP BY example
ANSWER
==================
D1 DPT SX
SAL R
-- --- -- ------ A A00 F
52750 1
A A00 M
75750 2
B B01 M
41250 1
C C01 F
90470 3
D D11 F
73430 3
D D11 M 148670 6
DESIRED SUB-TOTALS
==================
D1, DEPT, and SEX.
D1 and DEPT.
D1 and SEX.
D1.
SEX.
Grand total.
EQUIVILENT TO
=====================================
GROUP BY GROUPING SETS ((d1,dept,sex)
,(d1,dept)
,(d1,sex)
,(d1)
,(sex)
EQUIVILENT TO
,())
=======================
GROUP BY ROLLUP(d1,dept)
,ROLLUP(sex)
Figure 578, Sub-totals that we want to get
SELECT
FROM
*
(SELECT
d1
,dept
,sex
,INT(SUM(salary))
AS
AS
AS
AS
d1
dpt
sx
sal
,SMALLINT(COUNT(*))
AS #r
,SMALLINT(GROUPING(d1))
AS g1
,SMALLINT(GROUPING(dept)) AS gd
,SMALLINT(GROUPING(sex))
AS gs
FROM
EMPLOYEE_VIEW
ANSWER
GROUP BY CUBE(d1,dept,sex)
============================
)AS xxx
D1 DPT SX SAL
#R G1 GD GS
WHERE
(g1,gd,gs) = (0,0,0)
-- --- -- ------ -- -- -- -OR
(g1,gd,gs) = (0,0,1)
A A00 F
52750 1 0 0 0
OR
(g1,gd,gs) = (0,1,0)
A A00 M
75750 2 0 0 0
OR
(g1,gd,gs) = (0,1,1)
A A00 - 128500 3 0 0 1
OR
(g1,gd,gs) = (1,1,0)
A F
52750 1 0 1 0
OR
(g1,gd,gs) = (1,1,1)
A M
75750 2 0 1 0
ORDER BY 1,2,3;
A - 128500 3 0 1 1
B B01 M
41250 1 0 0 0
B B01 41250 1 0 0 1
B M
41250 1 0 1 0
B 41250 1 0 1 1
C C01 F
90470 3 0 0 0
C C01 90470 3 0 0 1
C F
90470 3 0 1 0
C 90470 3 0 1 1
D D11 F
73430 3 0 0 0
D D11 M 148670 6 0 0 0
D D11 - 222100 9 0 0 1
D F
73430 3 0 1 0
D M 148670 6 0 1 0
D - 222100 9 0 1 1
- F 216650 7 1 1 0
- M 265670 9 1 1 0
- - 482320 16 1 1 1
Figure 579, Get lots of sub-totals, using CUBE
(G1,GD,GS) = (0,0,0)
(G1,GD,GS) = (0,0,1)
(G1,GD,GS) = (0,1,0)
(G1,GD,GS) = (0,1,1)
(G1,GD,GS) = (1,1,0)
(G1,GD,GS) = (1,1,1)
Figure 580, Predicates
SELECT
<==
D1, DEPT, SEX
<==
D1, DEPT
<==
D1, SEX
<==
D1,
<==
SEX,
<==
grand total
used - explanation
d1
,dept
,sex
,INT(SUM(salary))
AS sal
,SMALLINT(COUNT(*)) AS #r
FROM
employee_view
GROUP BY ROLLUP(d1,dept)
,ROLLUP(sex)
ORDER BY 1,2,3;
ANSWER
=====================
D1 DEPT SEX
SAL #R
-- ---- --- ------ -A A00 F
52750 1
A A00 M
75750 2
A A00 128500 3
A F
52750 1
A M
75750 2
A 128500 3
B B01 M
41250 1
B B01 41250 1
B
B
C
C
C
C
D
D
D
D
D
D
-
C01
C01
D11
D11
D11
-
M
F
F
F
M
F
M
F
M
-
41250 1
41250 1
90470 3
90470 3
90470 3
90470 3
73430 3
148670 6
222100 9
73430 3
148670 6
222100 9
216650 7
265670 9
482320 16
SELECT
dept, job
,COUNT(*)
FROM
staff
GROUP BY dept, job
ORDER BY dept, job;
Figure 582, GROUP BY with ORDER BY
SELECT
FROM
a.id
,a.name
,a.dept
staff a
,(SELECT
dept
AS dept
,AVG(salary) AS avgsal
FROM
staff
GROUP BY dept
ANSWER
=================
ID NAME
DEPT
--- -------- ---160 Molinare
10
210 Lu
10
240 Daniels
10
260 Jones
10
HAVING
AVG(salary) > 18000
)AS b
WHERE
a.dept = b.dept
ORDER BY a.id;
Figure 584, GROUP BY on one side of join - using full-select
SELECT
FROM
WHERE
COUNT(*)
staff
id < 1;
AS c1
ANSWER
======
0
SELECT
COUNT(*) AS c1
FROM
staff
WHERE
id < 1
GROUP BY id;
Figure 585, COUNT and No Rows
CREATE
SELECT
FROM
WHERE
VIEW staff_v1 AS
id, name
staff
ID BETWEEN 10 AND 30;
ANSWER
======
no row
STAFF_V1
+-----------+
|ID|NAME
|
|--|--------|
|10|Sanders |
|20|Pernal |
|30|Marenghi|
+-----------+
STAFF_V2
+---------+
|ID|JOB
|
|--|------|
|20|Sales |
|30|Clerk |
|30|Mgr
|
|40|Sales |
|50|Mgr
|
+---------+
SELECT
v1.id
,v1.name
,v2.job
FROM
staff_v1 v1
,staff_v2 v2
WHERE
v1.id = v2.id
ORDER BY v1.id
,v2.job;
Figure 588, Sample two-table join
JOIN ANSWER
=================
ID NAME
JOB
-- -------- ----20 Pernal
Sales
30 Marenghi Clerk
30 Marenghi Mgr
SELECT
v1.id
,v2.job
,v3.name
FROM
staff_v1 v1
,staff_v2 v2
,staff_v1 v3
WHERE
v1.id = v2.id
AND
v2.id = v3.id
AND
v3.name LIKE 'M%'
ORDER BY v1.name
,v2.job;
Figure 589, Sample three-table join
JOIN ANSWER
=================
ID JOB
NAME
-- ----- -------30 Clerk Marenghi
30 Mgr
Marenghi
SELECT
v1.id
,v1.name
,v2.job
FROM
staff_v1 v1
INNER JOIN
staff_v2 v2
ON
v1.id = v2.id
ORDER BY v1.id
,v2.job;
Figure 591, Sample two-table inner join
SELECT
FROM
JOIN
ON
JOIN
v1.id
,v2.job
,v3.name
staff_v1 v1
staff_v2 v2
v1.id = v2.id
staff_v1 v3
ON
v2.id = v3.id
WHERE
v3.name LIKE 'M%'
ORDER BY v1.name
,v2.job;
JOIN ANSWER
=================
ID NAME
JOB
-- -------- ----20 Pernal
Sales
30 Marenghi Clerk
30 Marenghi Mgr
STAFF_V1
+-----------+
|ID|NAME
|
|--|--------|
|10|Sanders |
|20|Pernal |
|30|Marenghi|
+-----------+
JOIN ANSWER
=================
ID JOB
NAME
-- ----- -------30 Clerk Marenghi
30 Mgr
Marenghi
Figure 592, Sample three-table inner join
STAFF_V2
+---------+
|ID|JOB
|
|--|------|
|20|Sales |
|30|Clerk |
|30|Mgr
|
|40|Sales |
|50|Mgr
|
+---------+
SELECT
*
FROM
staff_v1 v1
LEFT OUTER JOIN
staff_v2 v2
ON
1
= 1
AND
v1.id
= v2.id
ORDER BY v1.id
,v2.job;
Figure 593, Sample Views used in Join Examples
ANSWER
====================
ID NAME
ID JOB
-- -------- -- ----10 Sanders - 20 Pernal
20 Sales
30 Marenghi 30 Clerk
30 Marenghi 30 Mgr
SELECT
*
FROM
staff_v1 v1
LEFT OUTER JOIN
staff_v2 v2
ON
1
= 1
WHERE
v1.id
= v2.id
ORDER BY v1.id
,v2.job;
Figure 594, Sample Views used in Join Examples
ANSWER
====================
ID NAME
ID JOB
-- -------- -- ----20 Pernal
20 Sales
30 Marenghi 30 Clerk
30 Marenghi 30 Mgr
STAFF_V1
+-----------+
|ID|NAME
|
|--|--------|
|10|Sanders |
|20|Pernal |
|30|Marenghi|
+-----------+
STAFF_V2
+---------+
|ID|JOB
|
Join on ID
|--|------|
==========>
|20|Sales |
|30|Clerk |
|30|Mgr
|
|40|Sales |
|50|Mgr
|
+---------+
Figure 595, Example of Inner Join
INNER-JOIN ANSWER
====================
ID NAME
ID JOB
-- -------- -- ----20 Pernal
20 Sales
30 Marenghi 30 Clerk
30 Marenghi 30 Mgr
SELECT
FROM
ANSWER
====================
ID NAME
ID JOB
-- -------- -- ----20 Pernal
20 Sales
30 Marenghi 30 Clerk
30 Marenghi 30 Mgr
*
staff_v1 v1
,staff_v2 v2
WHERE
v1.id = v2.id
ORDER BY v1.id
,v2.job;
Figure 596, Inner Join SQL (1 of 2)
SELECT
*
FROM
staff_v1 v1
INNER JOIN
staff_v2 v2
ON
v1.id = v2.id
ORDER BY v1.id
,v2.job;
Figure 597, Inner Join SQL (2 of 2)
ANSWER
====================
ID NAME
ID JOB
-- -------- -- ----20 Pernal
20 Sales
30 Marenghi 30 Clerk
30 Marenghi 30 Mgr
SELECT
*
FROM
staff_v1 v1
INNER JOIN
staff_v2 v2
ON
v1.id
= v2.id
AND
v2.job <> 'Mgr'
ORDER BY v1.id
,v2.job;
Figure 598, Inner join, using ON check
ANSWER
====================
ID NAME
ID JOB
-- -------- -- ----20 Pernal
20 Sales
30 Marenghi 30 Clerk
SELECT
*
FROM
staff_v1 v1
INNER JOIN
staff_v2 v2
ON
v1.id
= v2.id
WHERE
v2.job <> 'Mgr'
ORDER BY v1.id
,v2.job;
Figure 599, Inner join, using WHERE check
ANSWER
====================
ID NAME
ID JOB
-- -------- -- ----20 Pernal
20 Sales
30 Marenghi 30 Clerk
STAFF_V1
+-----------+
|ID|NAME
|
|--|--------|
|10|Sanders |
|20|Pernal |
|30|Marenghi|
+-----------+
STAFF_V2
+---------+
|ID|JOB
|
|--|------|
=========>
|20|Sales |
|30|Clerk |
|30|Mgr
|
|40|Sales |
|50|Mgr
|
+---------+
Figure 600, Example of Left Outer Join
LEFT-OUTER-JOIN ANSWER
======================
ID NAME
ID JOB
-- -------- -- ----10 Sanders - 20 Pernal
20 Sales
30 Marenghi 30 Clerk
30 Marenghi 30 Mgr
SELECT
*
FROM
staff_v1 v1
LEFT OUTER JOIN
staff_v2 v2
ON
v1.id = v2.id
ORDER BY 1,4;
Figure 601, Left Outer Join SQL (1 of 2)
SELECT
FROM
WHERE
UNION
SELECT
v1.*
,v2.*
staff_v1 v1
,staff_v2 v2
v1.id = v2.id
v1.*
,CAST(NULL AS SMALLINT) AS id
,CAST(NULL AS CHAR(5)) AS job
FROM
staff_v1 v1
WHERE
v1.id NOT IN
(SELECT id FROM staff_v2)
ORDER BY 1,4;
Figure 602, Left Outer Join SQL (2 of 2)
SELECT
*
FROM
staff_v1 v1
LEFT OUTER JOIN
staff_v2 v2
ON
v1.id
= v2.id
AND
v2.job <> 'Mgr'
ORDER BY v1.id
,v2.job;
Figure 603, ON check on table being joined to
ANSWER
====================
ID NAME
ID JOB
-- -------- -- ----10 Sanders - 20 Pernal
20 Sales
30 Marenghi 30 Clerk
SELECT
*
ANSWER
FROM
staff_v1 v1
====================
LEFT OUTER JOIN
ID NAME
ID JOB
staff_v2 v2
-- -------- -- ----ON
v1.id
= v2.id
20 Pernal
20 Sales
WHERE
v2.job <> 'Mgr'
30 Marenghi 30 Clerk
ORDER BY v1.id
,v2.job;
Figure 604, WHERE check on table being joined to (1 of 2)
SELECT
*
ANSWER
FROM
staff_v1 v1
====================
LEFT OUTER JOIN
ID NAME
ID JOB
staff_v2 v2
-- -------- -- ----ON
v1.id
= v2.id
10 Sanders - WHERE
(v2.job <> 'Mgr'
20 Pernal
20 Sales
OR
v2.job IS NULL)
30 Marenghi 30 Clerk
ORDER BY v1.id
,v2.job;
Figure 605, WHERE check on table being joined to (2 of 2)
SELECT
*
FROM
staff_v1 v1
LEFT OUTER JOIN
staff_v2 v2
ON
v1.id
= v2.id
AND
v1.name > 'N'
ORDER BY v1.id
,v2.job;
Figure 606, ON check on table being joined from
ANSWER
====================
ID NAME
ID JOB
-- -------- -- ----10 Sanders - 20 Pernal
20 Sales
30 Marenghi - -
SELECT
*
ANSWER
FROM
staff_v1 v1
====================
LEFT OUTER JOIN
ID NAME
ID JOB
staff_v2 v2
-- -------- -- ----ON
v1.id
= v2.id
10 Sanders - WHERE
v1.name > 'N'
20 Pernal
20 Sales
ORDER BY v1.id
,v2.job;
Figure 607, WHERE check on table being joined from
STAFF_V1
+-----------+
|ID|NAME
|
|--|--------|
|10|Sanders |
|20|Pernal |
|30|Marenghi|
+-----------+
STAFF_V2
+---------+
|ID|JOB
|
|--|------|
=========>
|20|Sales |
|30|Clerk |
|30|Mgr
|
|40|Sales |
|50|Mgr
|
+---------+
Figure 608, Example of Right Outer Join
RIGHT-OUTER-JOIN ANSWER
=======================
ID NAME
ID JOB
-- -------- -- ----20 Pernal
20 Sales
30 Marenghi 30 Clerk
30 Marenghi 30 Mgr
- 40 Sales
- 50 Mgr
SELECT
*
FROM
staff_v1 v1
RIGHT OUTER JOIN
staff_v2 v2
ON
v1.id = v2.id
ORDER BY v2.id
,v2.job;
Figure 609, Right Outer Join SQL (1 of 2)
SELECT
FROM
WHERE
UNION
SELECT
v1.*
,v2.*
staff_v1 v1
,staff_v2 v2
v1.id = v2.id
CAST(NULL AS SMALLINT)
AS id
,CAST(NULL AS VARCHAR(9)) AS name
,v2.*
FROM
staff_v2 v2
WHERE
v2.id NOT IN
(SELECT id FROM staff_v1)
ORDER BY 3,4;
Figure 610, Right Outer Join SQL (2 of 2)
STAFF_V1
+-----------+
|ID|NAME
|
|--|--------|
|10|Sanders |
|20|Pernal |
|30|Marenghi|
+-----------+
STAFF_V2
+---------+
|ID|JOB
|
|--|------|
=========>
|20|Sales |
|30|Clerk |
|30|Mgr
|
|40|Sales |
|50|Mgr
|
+---------+
Figure 611, Example of Full Outer Join
SELECT
*
FROM
staff_v1 v1
FULL OUTER JOIN
staff_v2 v2
ON
v1.id = v2.id
ORDER BY v1.id
,v2.id
,v2.job;
ANSWER
====================
ID NAME
ID JOB
-- -------- -- ----20 Pernal
20 Sales
30 Marenghi 30 Clerk
30 Marenghi 30 Mgr
- 40 Sales
- 50 Mgr
ANSWER
====================
ID NAME
ID JOB
-- -------- -- ----20 Pernal
20 Sales
30 Marenghi 30 Clerk
30 Marenghi 30 Mgr
- 40 Sales
- 50 Mgr
FULL-OUTER-JOIN ANSWER
======================
ID NAME
ID JOB
-- -------- -- ----10 Sanders - 20 Pernal
20 Sales
30 Marenghi 30 Clerk
30 Marenghi 30 Mgr
- 40 Sales
- 50 Mgr
ANSWER
====================
ID NAME
ID JOB
-- -------- -- ----10 Sanders - 20 Pernal
20 Sales
30 Marenghi 30 Clerk
30 Marenghi 30 Mgr
- - -
40 Sales
50 Mgr
SELECT
FROM
WHERE
UNION
SELECT
FROM
WHERE
UNION
SELECT
v1.*
,v2.*
staff_v1 v1
,staff_v2 v2
v1.id = v2.id
v1.*
,CAST(NULL AS SMALLINT) AS id
,CAST(NULL AS CHAR(5)) AS job
staff_v1 v1
v1.id NOT IN
(SELECT id FROM staff_v2)
ANSWER
====================
ID NAME
ID JOB
-- -------- -- ----10 Sanders - 20 Pernal
20 Sales
30 Marenghi 30 Clerk
30 Marenghi 30 Mgr
- 40 Sales
- 50 Mgr
CAST(NULL AS SMALLINT)
AS id
,CAST(NULL AS VARCHAR(9)) AS name
,v2.*
FROM
staff_v2 v2
WHERE
v2.id NOT IN
(SELECT id FROM staff_v1)
ORDER BY 1,3,4;
Figure 613, Full Outer Join SQL
SELECT
*
FROM
staff_v1 v1
FULL OUTER JOIN
staff_v2 v2
ON
v1.id = v2.id
ORDER BY v1.id
,v2.id
,v2.job;
ANSWER
====================
ID NAME
ID JOB
-- -------- -- ----10 Sanders
- 20 Pernal
20 Sales
30 Marenghi 30 Clerk
30 Marenghi 30 Mgr
- 40 Sales
- 50 Mgr
SELECT
*
FROM
staff_v1 v1
FULL OUTER JOIN
staff_v2 v2
ON
v1.id = v2.id
AND
v1.id > 20
ORDER BY v1.id
,v2.id
,v2.job;
ANSWER
====================
ID NAME
ID JOB
-- -------- -- ----10 Sanders
- 20 Pernal
- 30 Marenghi 30 Clerk
30 Marenghi 30 Mgr
- 20 Sales
- 40 Sales
- -
50 Mgr
SELECT
*
FROM
staff_v1 v1
FULL OUTER JOIN
staff_v2 v2
ON
v1.id = v2.id
AND
+1 = -1
ORDER BY v1.id
,v2.id
,v2.job;
ANSWER
====================
ID NAME
ID JOB
-- -------- -- ----10 Sanders
- 20 Pernal
- 30 Marenghi - - 20 Sales
- 30 Clerk
- 30 Mgr
- 40 Sales
- 50 Mgr
Figure 616, Full Outer Join, match on keys (no rows match)
SELECT
*
FROM
staff_v1 v1
FULL OUTER JOIN
staff_v2 v2
ON
+1 = -1
ORDER BY v1.id
,v2.id
,v2.job;
ANSWER
====================
ID NAME
ID JOB
-- -------- -- ----10 Sanders
- 20 Pernal
- 30 Marenghi - - 20 Sales
- 30 Clerk
- 30 Mgr
- 40 Sales
- 50 Mgr
Figure 617, Full Outer Join, don't match on keys (no rows match)
SELECT
*
FROM
staff_v1 v1
FULL OUTER JOIN
staff_v2 v2
ON
+1 <> -1
ORDER BY v1.id
,v2.id
,v2.job;
STAFF_V1
+-----------+
|ID|NAME
|
|--|--------|
|10|Sanders |
|20|Pernal |
|30|Marenghi|
STAFF_V2
+---------+
|ID|JOB
|
|--|------|
|20|Sales |
|30|Clerk |
|30|Mgr
|
ANSWER
====================
ID NAME
ID JOB
-- -------- -- ----10 Sanders 20 Sales
10 Sanders 30 Clerk
10 Sanders 30 Mgr
10 Sanders 40 Sales
10 Sanders 50 Mgr
20 Pernal
20 Sales
20 Pernal
30 Clerk
20 Pernal
30 Mgr
20 Pernal
40 Sales
20 Pernal
50 Mgr
30 Marenghi 20 Sales
30 Marenghi 30 Clerk
30 Marenghi 30 Mgr
+-----------+
|40|Sales |
30 Marenghi 40 Sales
|50|Mgr
|
30 Marenghi 50 Mgr
+---------+
Figure 618, Full Outer Join, don't match on keys (all rows match)
SELECT
*
FROM
staff_v1 v1
FULL JOIN
staff_v2 v2
ON
v1.id = v2.id
WHERE
v1.id = v2.id
ORDER BY 1,3,4;
Figure 619, Full Outer Join, turned into an inner
STAFF_V1
+-----------+
|ID|NAME
|
|--|--------|
|10|Sanders |
|20|Pernal |
|30|Marenghi|
+-----------+
ANSWER
====================
ID NAME
ID JOB
-- -------- -- ----20 Pernal
20 Sales
30 Marenghi 30 Clerk
30 Marenghi 30 Mgr
join by WHERE
STAFF_V2
+---------+
|ID|JOB
|
OUTER-JOIN CRITERIA
|--|------|
==================>
|20|Sales |
V1.ID = V2.ID
|30|Clerk |
V1.ID < 30
|30|Mgr
|
|40|Sales |
|50|Mgr
|
+---------+
Figure 620, Outer join V1.ID < 30, sample data
ANSWER
============
???, DEPENDS
SELECT
*
ANSWER
FROM
staff_v1 v1
====================
FULL JOIN
ID NAME
ID JOB
staff_v2 v2
-- -------- -- ----ON
v1.id = v2.id
10 Sanders - WHERE
v1.id < 30
20 Pernal
20 Sales
ORDER BY 1,3,4;
Figure 621, Outer join V1.ID < 30, check applied in WHERE (after join)
SELECT
*
FROM
staff_v1 v1
FULL JOIN
staff_v2 v2
ON
v1.id = v2.id
AND
v1.id < 30
ORDER BY 1,3,4;
ANSWER
====================
ID NAME
ID JOB
-- -------- -- ----10 Sanders - 20 Pernal
20 Sales
30 Marenghi - - 30 Clerk
- 30 Mgr
- 40 Sales
- 50 Mgr
Figure 622, Outer join V1.ID < 30, check applied in ON (during join)
SELECT
FROM
*
(SELECT *
FROM
staff_v1
WHERE id < 30) AS v1
FULL OUTER JOIN
staff_v2 v2
ON
v1.id = v2.id
ORDER BY 1,3,4;
ANSWER
====================
ID NAME
ID JOB
-- -------- -- ----10 Sanders - 20 Pernal
20 Sales
- 30 Clerk
- 30 Mgr
- 40 Sales
- 50 Mgr
Figure 623, Outer join V1.ID < 30, check applied in WHERE (before join)
SELECT
*
FROM
staff_v1
FULL OUTER JOIN
staff_v2
ON
v1.id =
WHERE
v1.id <
OR
v1.id IS
ORDER BY 1,3,4;
Figure 624, Outer
SELECT
*
FROM
staff_v1
FULL OUTER JOIN
staff_v2
ON
v1.id =
WHERE
v1.id <
OR
v1.id =
OR
v1.id IS
ORDER BY 1,3,4;
ANSWER
====================
ID NAME
ID JOB
v2
-- -------- -- ----v2.id
10 Sanders - 30
20 Pernal
20 Sales
NULL
- 40 Sales
- 50 Mgr
join V1.ID < 30, (gives wrong answer - see text)
v1
ANSWER
====================
ID NAME
ID JOB
v2
-- -------- -- ----v2.id
10 Sanders - 30
20 Pernal
20 Sales
v2.id
30 Marenghi 30 Clerk
NULL
30 Marenghi 30 Mgr
- 40 Sales
- 50 Mgr
Figure 625, Outer join V1.ID < 30, (gives wrong answer - see text)
STAFF_V1
+-----------+
|ID|NAME
|
|--|--------|
v1
STAFF_V2
+---------+
|ID|JOB
|
|--|------|
=========>
CARTESIAN-PRODUCT
====================
ID NAME
ID JOB
-- -------- -- -----
|10|Sanders |
|20|Pernal |
|30|Marenghi|
+-----------+
|20|Sales |
|30|Clerk |
|30|Mgr
|
|40|Sales |
|50|Mgr
|
+---------+
10
10
10
10
10
20
20
20
20
20
30
30
30
30
30
Sanders
Sanders
Sanders
Sanders
Sanders
Pernal
Pernal
Pernal
Pernal
Pernal
Marenghi
Marenghi
Marenghi
Marenghi
Marenghi
20
30
30
40
50
20
30
30
40
50
20
30
30
40
50
Sales
Clerk
Mgr
Sales
Mgr
Sales
Clerk
Mgr
Sales
Mgr
Sales
Clerk
Mgr
Sales
Mgr
SELECT
FROM
*
staff_v1 v1
,staff_v2 v2
ORDER BY v1.id
,v2.id
,v2.job;
Figure 627, Cartesian Product SQL (1 of 2)
SELECT
*
FROM
staff_v1 v1
INNER JOIN
staff_v2 v2
ON
'A' <> 'B'
ORDER BY v1.id
,v2.id
,v2.job;
Figure 628, Cartesian Product SQL (2 of 2)
SELECT
v2a.id
,v2a.job
,v2b.id
FROM
staff_v2 v2a
,staff_v2 v2b
WHERE
v2a.job = v2b.job
AND
v2a.id < 40
ORDER BY v2a.id
,v2b.id;
Figure 629, Partial Cartesian Product SQL
ANSWER
===========
ID JOB
ID
-- ----- -20 Sales 20
20 Sales 40
30 Clerk 30
30 Mgr
30
30 Mgr
50
SELECT
v2.job
,COUNT(*) AS #rows
FROM
staff_v1 v1
,staff_v2 v2
GROUP BY v2.job
ORDER BY #rows
,v2.job;
Figure 630, Partial Cartesian Product SQL, with GROUP BY
ANSWER
===========
JOB
#ROWS
----- ----Clerk
3
Mgr
6
Sales
6
SELECT
ANSWER
=================
ID NAME
JOB
-- -------- ----10 Sanders 20 Pernal
Sales
30 Marenghi Clerk
30 Marenghi Mgr
40 ?
Sales
50 ?
Mgr
COALESCE(v1.id,v2.id) AS id
,COALESCE(v1.name,'?') AS name
,v2.job
FROM
staff_v1 v1
FULL OUTER JOIN
staff_v2 v2
ON
v1.id = v2.id
ORDER BY v1.id
,v2.job;
Figure 631, Use of COALESCE function in outer join
STAFF_V1
+-----------+
|ID|NAME
|
|--|--------|
|10|Sanders |
|20|Pernal |
|30|Marenghi|
+-----------+
STAFF_V2
ANSWER
+---------+
NON-MATCHING
===================
|ID|JOB
|
OUTER-JOIN
ID NAME
ID JOB
|--|------|
===========>
-- ------- -- ----|20|Sales |
10 Sanders - |30|Clerk |
- 40 Sales
|30|Mgr
|
- 50 Mgr
|40|Sales |
|50|Mgr
|
+---------+
Figure 632, Example of outer join, only getting the non-matching rows
SELECT
FROM
WHERE
UNION
SELECT
FROM
WHERE
v1.*
,CAST(NULL AS SMALLINT) AS id
,CAST(NULL AS CHAR(5)) AS job
staff_v1 v1
v1.id NOT IN
(SELECT id FROM staff_v2)
CAST(NULL AS SMALLINT)
AS id
,CAST(NULL AS VARCHAR(9)) AS name
,v2.*
staff_v2 v2
v2.id NOT IN
SELECT
*
FROM
(SELECT v1.*
,'V1' AS flag
FULL OUTER JOIN
(SELECT v2.*
,'V2' AS flag
ON
v1.id = v2.id
WHERE
v1.flag IS NULL
OR
v2.flag IS NULL
ORDER BY v1.id
,v2.id
,v2.job;
ANSWER
=============================
ID NAME
FLAG ID JOB
FLAG
-- ------- ---- -- ----- ---10 Sanders V1
- - 40 Sales V2
- 50 Mgr
V2
Figure 634, Outer Join SQL, getting only non-matching rows
WITH
v1 AS (SELECT v1.*
,'V1' AS flag
FROM staff_v1 v1)
,v2 AS (SELECT v2.*
,'V2' AS flag
FROM staff_v2 v2)
SELECT *
FROM
v1 v1
ANSWER
FULL OUTER JOIN
=============================
v2 v2
ID NAME
FLAG ID JOB
FLAG
ON
v1.id = v2.id
-- ------- ---- -- ----- ---WHERE
v1.flag IS NULL
10 Sanders V1
- OR
v2.flag IS NULL
- 40 Sales V2
ORDER BY v1.id, v2.id, v2.job;
- 50 Mgr
V2
Figure 635, Outer Join SQL, getting only non-matching rows
SELECT
*
FROM
staff_v1
FULL OUTER JOIN
staff_v2
ON
v1.id =
WHERE
v1.id IS
OR
v2.id IS
ORDER BY v1.id
,v2.id
,v2.job;
Figure 636, Outer
v1
v2
v2.id
NULL
NULL
STAFF_V1
+-----------+
|ID|NAME
|
|--|--------|
|10|Sanders |
|20|Pernal |
|30|Marenghi|
+-----------+
STAFF_V2
+---------+
|ID|JOB
|
|--|------|
|20|Sales |
|30|Clerk |
|30|Mgr
|
|40|Sales |
|50|Mgr
|
+---------+
STAFF_V1
+-----------+
|ID|NAME
|
|--|--------|
|10|Sanders |
|20|Pernal |
|30|Marenghi|
+-----------+
STAFF_V2
+---------+
LEFT OUTER JOIN
|ID|JOB
|
==============>
|--|------|
V1.ID = V2.ID
|20|Sales |
V1.ID <> 30
|30|Clerk |
|30|Mgr
|
|40|Sales |
|50|Mgr
|
+---------+
Figure 637, Left outer join example
SELECT
v1.id
,v1.name
,v2.job
FROM
staff_v1
LEFT OUTER JOIN
staff_v2
ON
v1.id =
WHERE
v1.id <>
ORDER BY v1.id ;
Figure 638, Outer
ANSWER
===================
ID NAME
ID JOB
-- ------- -- ----10 Sanders - 20 Pernal 20 Sales
v1.id
,v1.name
,(SELECT
FROM
WHERE
FROM
staff_v1
WHERE
v1.id <>
ORDER BY v1.id;
Figure 639, Outer
v1
v2
v2.id
30
Join done in FROM phrase of SQL
SELECT
v1.id
,v1.name
,(SELECT
FROM
WHERE
FROM
staff_v1
ORDER BY v1.id;
Figure 640, Outer
v2.job
staff_v2 v2
v1.id = v2.id) AS jb
v1
30
v1.id
ANSWER
=================
ID NAME
JB
-- -------- ----10 Sanders 20 Pernal
Sales
SELECT
SELECT
ANSWER
=================
ID NAME
JOB
-- -------- ----10 Sanders 20 Pernal
Sales
v2.job
staff_v2 v2
v1.id = v2.id) AS jb
v1
ANSWER
=================
ID NAME
JB
-- -------- ----10 Sanders 20 Pernal
Sales
ANSWER
,v1.name
,(SELECT
FROM
WHERE
FROM
staff_v1
ORDER BY v1.id;
Figure 641, Outer
=================
ID NAME
JB
-- -------- ----10 Sanders 20 Pernal
Sales
30 Marenghi Mgr
Join done in SELECT phrase of SQL - fixed
MAX(v2.job)
staff_v2 v2
v1.id = v2.id) AS jb
v1
SELECT
v1.id
ANSWER
,v1.name
=================
,MAX(v2.job) AS jb
ID NAME
JB
FROM
staff_v1 v1
-- -------- ----LEFT OUTER JOIN
10 Sanders staff_v2 v2
20 Pernal
Sales
ON
v1.id = v2.id
30 Marenghi Mgr
GROUP BY v1.id
,v1.name
ORDER BY v1.id ;
Figure 642, Same as prior query - using join and GROUP BY
SELECT
v2.id
,CASE
WHEN v2.job <> 'Mgr'
THEN v2.job
ELSE (SELECT v1.name
FROM
staff_v1 v1
WHERE v1.id = v2.id)
END AS j2
FROM
staff_v2 v2
ORDER BY v2.id
,j2;
Figure 643, Sample Views used in Join Examples
ANSWER
===========
ID J2
-- -------20 Sales
30 Clerk
30 Marenghi
40 Sales
50 -
SELECT
ANSWER
====================
ID JOB
NAME
N2
-- ----- -------- -20 Sales Pernal
6
30 Clerk Marenghi 8
30 Mgr
Marenghi 8
40 Sales 50 Mgr
-
v2.id
,v2.job
,(SELECT
FROM
WHERE
,(SELECT
FROM
WHERE
FROM
staff_v2
ORDER BY v2.id
,v2.job;
Figure 644, Outer
v1.name
staff_v1 v1
v2.id = v1.id)
LENGTH(v1.name) AS n2
staff_v1 v1
v2.id = v1.id)
v2
Join done in SELECT, 2 columns
SELECT
v2.id
,v2.job
,v1.name
,LENGTH(v1.name) AS n2
FROM
staff_v2 v2
LEFT OUTER JOIN
staff_v1 v1
ON
v2.id = v1.id
ORDER BY v2.id
,v2.job;
Figure 645, Outer Join done in FROM, 2 columns
ANSWER
====================
ID JOB
NAME
N2
-- ----- -------- -20 Sales Pernal
6
30 Clerk Marenghi 8
30 Mgr
Marenghi 8
40 Sales 50 Mgr
-
SELECT
v1.id
,v1.name
,(SELECT SUM(x1.id)
FROM
staff_v1 x1
WHERE
x1.id <= v1.id
)AS sum_id
FROM
staff_v1 v1
ORDER BY v1.id
,v2.job;
Figure 646, Running total, using JOIN in SELECT
ANSWER
==================
ID NAME
SUM_ID
-- -------- -----10 Sanders
10
20 Pernal
30
30 Marenghi
60
SELECT
ANSWER
==================
ID NAME
SUM_ID
-- -------- -----10 Sanders
10
20 Pernal
30
30 Marenghi
60
v1.id
,v1.name
,SUM(id) OVER(ORDER BY id) AS sum_id
FROM
staff_v1 v1
ORDER BY v1.id;
Figure 647, Running total, using OLAP function
STAFF_V1
+-----------+
|ID|NAME
|
|--|--------|
|10|Sanders |
|20|Pernal |
|30|Marenghi|
+-----------+
STAFF_V2
+---------+
|ID|JOB
|
OUTER-JOIN CRITERIA
|--|------|
==================>
|20|Sales |
V1.ID
= V2.ID
|30|Clerk |
V2.JOB LIKE 'S%'
|30|Mgr
|
|40|Sales |
|50|Mgr
|
+---------+
Figure 648, Outer join, with WHERE filter
ANSWER
=================
ID NAME
JOB
-- -------- ----10 Sanders 20 Pernal
Sales
30 Marenghi -
SELECT
v1.id
,v1.name
,v2.job
FROM
staff_v1 v1
LEFT OUTER JOIN
staff_v2 v2
ON
v1.id
= v2.id
WHERE
v2.job LIKE 'S%'
ORDER BY v1.id
,v2.job;
Figure 649, Outer Join, WHERE done after - wrong
ANSWER (WRONG)
=================
ID NAME
JOB
-- -------- ----20 Pernal
Sales
SELECT
ANSWER
=================
ID NAME
JOB
-- -------- ----10 Sanders 20 Pernal
Sales
30 Marenghi -
v1.id
,v1.name
,v2.job
FROM
staff_v1 v1
LEFT OUTER JOIN
(SELECT *
FROM
staff_v2
WHERE
job LIKE 'S%'
)AS v2
ON
v1.id = v2.id
ORDER BY v1.id
,v2.job;
Figure 650, Outer Join, WHERE done before - correct
SELECT
v1.id
ANSWER
,v1.name
=================
,(SELECT v2.job
ID NAME
JOB
FROM
staff_v2 v2
-- -------- ----WHERE v1.id
= v2.id
10 Sanders AND v2.job LIKE 'S%')
20 Pernal
Sales
FROM
staff_v1 v1
30 Marenghi ORDER BY v1.id
,job;
Figure 651, Outer Join, WHERE done independently - correct
SELECT
eee.empno
,aaa.projno
,aaa.actno
,ppp.photo_format AS format
FROM
employee
eee
LEFT OUTER JOIN
emp_act
aaa
ANSWER
==========================
EMPNO PROJNO ACTNO FORMAT
------ ------ ----- -----000010 MA2110
10 000070 - 000130 - bitmap
ON
eee.empno
=
AND
aaa.emptime
=
AND
aaa.projno
LIKE
LEFT OUTER JOIN
emp_photo ppp
ON
eee.empno
=
AND
ppp.photo_format LIKE
WHERE
eee.lastname
LIKE
AND
eee.empno
<
AND
eee.empno
<>
ORDER BY eee.empno;
Figure 652, Join from Employee
aaa.empno
1
'M%1%'
60 bitmap
180 bitmap
60 -
ppp.empno
'b%'
'%A%'
'000170'
'000030'
to Activity and Photo
SELECT
eee.empno
,aaa.projno
,aaa.actno
,ppp.photo_format AS format
FROM
employee
eee
LEFT OUTER JOIN
emp_act
aaa
ON
eee.empno
= aaa.empno
AND
aaa.emptime
= 1
AND
aaa.projno
LIKE 'M%1%'
LEFT OUTER JOIN
emp_photo ppp
ON
aaa.empno
= ppp.empno
AND
ppp.photo_format LIKE 'b%'
WHERE
eee.lastname
LIKE '%A%'
AND
eee.empno
< '000170'
AND
eee.empno
<> '000030'
ORDER BY eee.empno;
Figure 653, Join from Employee to Activity,
SELECT
000150 MA2112
000150 MA2112
000160 MA2113
ddd.deptno AS dp#
,eee.empno
,aaa.projno
,ppp.projname
FROM
(SELECT *
FROM
department
WHERE
deptname
LIKE '%A%'
AND
deptname NOT LIKE '%U%'
AND
deptno
< 'E'
)AS ddd
INNER JOIN
employee
eee
ON
ddd.deptno
= eee.workdept
AND
eee.lastname LIKE '%A%'
LEFT OUTER JOIN
emp_act
aaa
ON
aaa.empno
= eee.empno
AND
aaa.emptime
<= 0.5
INNER JOIN
project
ppp
ANSWER
==========================
EMPNO PROJNO ACTNO FORMAT
------ ------ ----- -----000010 MA2110
10 000070 - 000130 - 000150 MA2112
60 bitmap
000150 MA2112
180 bitmap
000160 MA2113
60 -
ON
aaa.projno
AND
ppp.projname
ORDER BY ddd.deptno
,eee.empno
,aaa.projno;
= ppp.projno
LIKE '%Q%'
ANSWER
================================
DP# EMPNO PROJNO PROJNAME
--- ------ ------ -------------C01 000030 IF1000 QUERY SERVICES
C01 000130 IF1000 QUERY SERVICES
SELECT
ddd.deptno AS dp#
,eee.empno
,xxx.projno
,xxx.projname
FROM
(SELECT *
FROM
department
WHERE
deptname
LIKE '%A%'
AND
deptname NOT LIKE '%U%'
AND
deptno
< 'E'
)AS ddd
INNER JOIN
employee
eee
ON
ddd.deptno
= eee.workdept
AND
eee.lastname LIKE '%A%'
LEFT OUTER JOIN
(SELECT
aaa.empno
,aaa.emptime
,aaa.projno
,ppp.projname
FROM
emp_act
aaa
INNER JOIN
project
ppp
ON
aaa.projno
= ppp.projno
AND
ppp.projname LIKE '%Q%'
)AS xxx
ON
xxx.empno
= eee.empno
AND
xxx.emptime
<= 0.5
ORDER BY ddd.deptno
,eee.empno
ANSWER
,xxx.projno;
================================
DP# EMPNO PROJNO PROJNAME
--- ------ ------ -------------C01 000030 IF1000 QUERY SERVICES
C01 000130 IF1000 QUERY SERVICES
D21 000070 D21 000240 Figure 655, Complex join - right
NOT NULL
NOT NULL
TABLE1
+-------+
|T1A|T1B|
|---|---|
TABLE2
+-----------+
|T2A|T2B|T2C|
|---|---|---|
COMMIT;
CREATE TABLE table2
(t2a
CHAR(1)
,t2b
CHAR(1)
,t2c
CHAR(1));
|A |AA |
|B |BB |
|C |CC |
+-------+
NOT NULL
NOT NULL
|A |A |A |
|B |A | - |
+-----------+
"-" = null
SELECT *
FROM
table1
WHERE t1a =
(SELECT t2a
FROM
table2
WHERE t2a = 'A');
ANSWER
=======
T1A T1B
--- -A
AA
SUB-Q
RESLT
+---+
|T2A|
|---|
|A |
+---+
TABLE1
+-------+
|T1A|T1B|
|---|---|
|A |AA |
|B |BB |
|C |CC |
+-------+
TABLE2
+-----------+
|T2A|T2B|T2C|
|---|---|---|
|A |A |A |
|B |A | - |
+-----------+
"-" = null
SELECT *
FROM
table1
WHERE t1a =
(SELECT t2a
FROM
table2);
SUB-Q
RESLT
+---+
|T2A|
|---|
|A |
|B |
+---+
Figure 659, No keyword sub-query, fails
ANSWER
=======
TABLE1
+-------+
|T1A|T1B|
|---|---|
|A |AA |
|B |BB |
|C |CC |
+-------+
TABLE2
+-----------+
|T2A|T2B|T2C|
|---|---|---|
|A |A |A |
|B |A | - |
+-----------+
"-" = null
SELECT *
FROM
table1
WHERE t1a > ANY
(SELECT t2a
FROM
table2);
ANSWER
=======
T1A T1B
--- -B
BB
C
CC
SUB-Q
RESLT
+---+
|T2A|
|---|
|A |
|B |
+---+
TABLE1
+-------+
|T1A|T1B|
|---|---|
|A |AA |
|B |BB |
|C |CC |
+-------+
TABLE2
+-----------+
|T2A|T2B|T2C|
|---|---|---|
|A |A |A |
|B |A | - |
+-----------+
"-" = null
SUB-QUERY CHECK
================
> ANY(sub-qurey)
< ANY(sub-query)
> ALL(sub-query)
> MAXIMUM(sub-query results)
< ALL(sub-query)
< MINIMUM(sub-query results)
Figure 661, ANY and ALL vs. column functions
SELECT *
FROM
table1
WHERE t1a = ALL
(SELECT t2b
FROM
table2
WHERE t2b >= 'A');
ANSWER
=======
T1A T1B
--- -A
AA
SELECT *
FROM
table1
WHERE t1a = ALL
(SELECT t2b
FROM
table2
WHERE t2b >= 'X');
ANSWER
=======
T1A T1B
--- -A
AA
B
BB
C
CC
SUB-Q
RESLT
+---+
|T2B|
|---|
|A |
|A |
+---+
SUB-Q
RESLT
+---+
|T2B|
|---|
+---+
SELECT *
FROM
table1
WHERE t1a = ALL
ANSWER
======
0 rows
(SELECT
FROM
WHERE
AND 0 <>
(SELECT
FROM
WHERE
t2b
table2
t2b >= 'X')
TABLE1
TABLE2
+-------+ +-----------+
|T1A|T1B| |T2A|T2B|T2C|
COUNT(*)
|---|---| |---|---|---|
table2
|A |AA | |A |A |A |
t2b >= 'X');
|B |BB | |B |A | - |
|C |CC | +-----------+
+-------+ "-" = null
Figure 664, ALL sub-query, with extra check for empty set
SELECT *
FROM
table1
WHERE EXISTS
(SELECT *
FROM
table2);
SQ-#1
RESLT
+---+
|T2B|
|---|
+---+
SQ-#2
RESLT
+---+
|(*)|
|---|
|0 |
+---+
ANSWER
=======
T1A T1B
--- -A
AA
B
BB
C
CC
TABLE1
+-------+
|T1A|T1B|
|---|---|
|A |AA |
|B |BB |
|C |CC |
+-------+
Figure 665, EXISTS sub-query, always returns a match
SELECT *
FROM
table1
WHERE EXISTS
(SELECT *
FROM
table2
WHERE t2b >= 'X');
Figure 666, EXISTS sub-query, always returns a non-match
TABLE2
+-----------+
|T2A|T2B|T2C|
|---|---|---|
|A |A |A |
|B |A | - |
+-----------+
"-" = null
ANSWER
======
0 rows
SELECT *
FROM
table1
WHERE EXISTS
(SELECT COUNT(*)
FROM
table2
WHERE t2b = 'X');
ANSWER
=======
T1A T1B
--- -A
AA
B
BB
C
CC
TABLE1
+-------+
|T1A|T1B|
|---|---|
|A |AA |
|B |BB |
|C |CC |
+-------+
Figure 667, EXISTS sub-query, always returns a match
TABLE2
+-----------+
|T2A|T2B|T2C|
|---|---|---|
|A |A |A |
|B |A | - |
+-----------+
"-" = null
SELECT *
FROM
table1
WHERE NOT EXISTS
(SELECT *
ANSWERS
=======
T1A T1B
--- ---
TABLE2
+-----------+
|T2A|T2B|T2C|
|---|---|---|
TABLE1
+-------+
|T1A|T1B|
|---|---|
FROM
WHERE
AND
table2
t2c >= 'A'
t2c <> t1a);
AA
|A |AA |
|B |BB |
|C |CC |
+-------+
|A |A |A |
|B |A | - |
+-----------+
"-" = null
SELECT *
FROM
table1
WHERE t1a = ALL
(SELECT t2c
FROM
table2
WHERE t2c >= 'A');
Figure 668, NOT EXISTS vs. ALL, ignore nulls, find match
SELECT *
FROM
table1
WHERE NOT EXISTS
(SELECT *
FROM
table2
WHERE t2c >= 'X'
AND t2c <> t1a);
ANSWERS
=======
T1A T1B
--- --A
AA
B
BB
C
CC
TABLE1
+-------+
|T1A|T1B|
|---|---|
|A |AA |
|B |BB |
|C |CC |
+-------+
TABLE2
+-----------+
|T2A|T2B|T2C|
|---|---|---|
|A |A |A |
|B |A | - |
+-----------+
"-" = null
SELECT *
FROM
table1
WHERE t1a = ALL
(SELECT t2c
FROM
table2
WHERE t2c >= 'X');
Figure 669, NOT EXISTS vs. ALL, ignore nulls, no match
SELECT *
FROM
table1
WHERE NOT EXISTS
(SELECT *
FROM
table2
WHERE t2c <> t1a);
ANSWER
=======
T1A T1B
--- --A
AA
TABLE1
+-------+
|T1A|T1B|
|---|---|
|A |AA |
|B |BB |
|C |CC |
+-------+
TABLE2
+-----------+
|T2A|T2B|T2C|
|---|---|---|
|A |A |A |
|B |A | - |
+-----------+
"-" = null
SELECT *
ANSWER
FROM
table1
=======
WHERE t1a = ALL
no rows
(SELECT t2c
FROM
table2);
Figure 670, NOT EXISTS vs. ALL, process nulls
SELECT *
FROM
table2
WHERE t2c <> 'A';
SELECT *
FROM
table2
WHERE t2c <> 'B';
SELECT *
FROM
table2
WHERE t2c <> 'C';
ANSWER
ANSWER
===========
===========
T2A T2B T2C
T2A T2B T2C
--- --- ----- --- --no rows
A
A
A
Figure 671, List of values in T2C <> T1A value
SELECT *
FROM
table1
WHERE NOT EXISTS
(SELECT *
FROM
table2
WHERE t2c <> t1a
OR t2c IS NULL);
ANSWER
=======
no rows
TABLE1
+-------+
|T1A|T1B|
|---|---|
|A |AA |
|B |BB |
|C |CC |
+-------+
TABLE2
+-----------+
|T2A|T2B|T2C|
|---|---|---|
|A |A |A |
|B |A | - |
+-----------+
"-" = null
ANSWER
=======
T1A T1B
--- -A
AA
B
BB
TABLE1
+-------+
|T1A|T1B|
|---|---|
|A |AA |
|B |BB |
|C |CC |
+-------+
TABLE2
+-----------+
|T2A|T2B|T2C|
|---|---|---|
|A |A |A |
|B |A | - |
+-----------+
"-" = null
SELECT *
FROM
table1
WHERE t1a IN
(SELECT t2a
FROM
table2);
ANSWER
===========
T2A T2B T2C
--- --- --A
A
A
SELECT *
FROM
table1
WHERE t1a IN
(SELECT t2a
FROM
table2
WHERE t2a >= 'X');
Figure 674, IN sub-query example, no matches
SELECT *
FROM
table2
WHERE t2c IN
(SELECT t2c
FROM
table2);
SELECT *
ANSWERS
===========
T2A T2B T2C
--- --- --A
A
A
ANSWER
======
0 rows
TABLE2
+-----------+
|T2A|T2B|T2C|
|---|---|---|
|A |A |A |
|B |A | - |
+-----------+
FROM
WHERE
table2
t2c = ANY
(SELECT t2c
FROM
table2);
Figure 675, IN and = ANY sub-query examples, with nulls
"-" = null
SELECT *
FROM
table1
WHERE t1a NOT IN
(SELECT t2c
FROM
table2);
TABLE1
+-------+
|T1A|T1B|
|---|---|
|A |AA |
|B |BB |
|C |CC |
+-------+
Figure 676, NOT IN sub-query example, no matches
TABLE2
+-----------+
|T2A|T2B|T2C|
|---|---|---|
|A |A |A |
|B |A | - |
+-----------+
"-" = null
SELECT *
FROM
table1
WHERE t1a NOT IN
(SELECT t2c
FROM
table2
WHERE t2c IS NOT NULL);
TABLE1
+-------+
|T1A|T1B|
|---|---|
|A |AA |
|B |BB |
|C |CC |
+-------+
TABLE2
+-----------+
|T2A|T2B|T2C|
|---|---|---|
|A |A |A |
|B |A | - |
+-----------+
"-" = null
ANSWER
======
0 rows
ANSWER
=======
T1A T1B
--- -B
BB
C
CC
SELECT *
FROM
table1
WHERE NOT EXISTS
(SELECT *
FROM
table2
WHERE t1a = t2c);
ANSWER
=======
T1A T1B
--- -B
BB
C
CC
TABLE1
+-------+
|T1A|T1B|
|---|---|
|A |AA |
|B |BB |
|C |CC |
+-------+
Figure 678, NOT EXISTS sub-query example, matches
TABLE2
+-----------+
|T2A|T2B|T2C|
|---|---|---|
|A |A |A |
|B |A | - |
+-----------+
"-" = null
SELECT *
FROM
table1
WHERE t1a IN
(SELECT t2a
FROM
table2);
ANSWER
=======
T1A T1B
--- -A
AA
B
BB
TABLE2
+-----------+
|T2A|T2B|T2C|
|---|---|---|
|A |A |A |
|B |A | - |
+-----------+
TABLE1
+-------+
|T1A|T1B|
|---|---|
|A |AA |
|B |BB |
|C |CC |
+-------+
"-" = null
TABLE1
+-------+
|T1A|T1B|
|---|---|
|A |AA |
|B |BB |
|C |CC |
+-------+
TABLE2
+-----------+
|T2A|T2B|T2C|
|---|---|---|
|A |A |A |
|B |A | - |
+-----------+
"-" = null
ANSWER
===========
T2A T2B T2C
--- --- --A
A
A
TABLE2
+-----------+
|T2A|T2B|T2C|
|---|---|---|
|A |A |A |
|B |A | - |
+-----------+
"-" = null
SELECT *
FROM
table1
WHERE t1a IN
(SELECT t2a
FROM
table2
WHERE t1a = t2a);
ANSWER
=======
T1A T1B
--- -A
AA
B
BB
SELECT *
FROM
table2
WHERE EXISTS
(SELECT
FROM
WHERE
aa
*
table2 bb
aa.t2a = bb.t2b);
SELECT *
FROM
table1
WHERE (t1a,t1b) IN
(SELECT t2a, t2b
FROM
table2);
ANSWER
======
0 rows
TABLE1
+-------+
|T1A|T1B|
|---|---|
|A |AA |
|B |BB |
|C |CC |
+-------+
TABLE2
+-----------+
|T2A|T2B|T2C|
|---|---|---|
|A |A |A |
|B |A | - |
+-----------+
"-" = null
SELECT *
ANSWER
FROM
table1
======
WHERE EXISTS
0 rows
(SELECT
*
FROM
table2
WHERE
t1a = t2a
AND
t1b = t2b);
Figure 682, Multi-field sub-queries, equal checks
SELECT *
FROM
table1
WHERE EXISTS
ANSWER
=======
T1A T1B
TABLE1
+-------+
|T1A|T1B|
TABLE2
+-----------+
|T2A|T2B|T2C|
(SELECT
FROM
WHERE
AND
*
table2
t1a = t2a
t1b >= t2b);
--- -A
AA
B
BB
|---|---|
|A |AA |
|B |BB |
|C |CC |
+-------+
Figure 683, Multi-field sub-query, with non-equal check
SELECT empno
,lastname
,salary
FROM
employee
WHERE salary >
(SELECT MAX(salary)
FROM
employee
WHERE empno NOT IN
(SELECT empno
FROM
emp_act
WHERE projno LIKE 'MA%'))
ORDER BY 1;
Figure 684, Nested Sub-Queries
|---|---|---|
|A |A |A |
|B |A | - |
+-----------+
"-" = null
ANSWER
=========================
EMPNO LASTNAME SALARY
------ --------- -------000010 HAAS
52750.00
000110 LUCCHESSI 46500.00
SELECT
COUNT(*)
AS #rows
,MAX(deptno) AS maxdpt
FROM
department
WHERE
deptname LIKE 'Z%'
ORDER BY 1;
Figure 685, Getting a null value from a not null field
ANSWER
=============
#ROWS MAXDEPT
----- ------0
null
SELECT *
FROM
table1
WHERE 0 =
(SELECT
FROM
WHERE
TABLE2
+-----------+
|T2A|T2B|T2C|
|---|---|---|
|A |A |A |
|B |A | - |
+-----------+
"-" = null
t1
COUNT(*)
table2 t2
t1.t1a = t2.t2c);
SELECT *
FROM
table1 t1
WHERE NOT EXISTS
(SELECT *
FROM
table2 t2
WHERE t1.t1a = t2.t2c);
SELECT *
FROM
table1
WHERE t1a NOT IN
(SELECT t2c
FROM
table2
WHERE t2c IS NOT NULL);
TABLE1
+-------+
|T1A|T1B|
|---|---|
|A |AA |
|B |BB |
|C |CC |
+-------+
ANSWER
=======
T1A T1B
--- --B
BB
C
CC
SELECT t1.*
FROM
table1 t1
LEFT OUTER JOIN
table2 t2
ON
t1.t1a = t2.t2c
WHERE t2.t2c IS NULL;
Figure 687, Outer join, true if none match
SELECT *
FROM
table1
WHERE EXISTS
(SELECT
FROM
WHERE
SELECT *
FROM
table1
WHERE 1 <=
(SELECT
FROM
WHERE
t1
*
table2 t2
t1.t1a = t2.t2c);
ANSWER
=======
T1A T1B
--- --B
BB
C
CC
TABLE1
+-------+
|T1A|T1B|
|---|---|
|A |AA |
|B |BB |
|C |CC |
+-------+
TABLE2
+-----------+
|T2A|T2B|T2C|
|---|---|---|
|A |A |A |
|B |A | - |
+-----------+
"-" = null
t1
COUNT(*)
table2 t2
t1.t1a = t2.t2c);
ANSWER
=======
T1A T1B
--- --A
AA
SELECT *
FROM
table1
WHERE t1a = ANY
(SELECT t2c
FROM
table2);
SELECT *
FROM
table1
WHERE t1a = SOME
(SELECT t2c
FROM
table2);
SELECT *
FROM
table1
WHERE t1a IN
(SELECT t2c
FROM
table2);
Figure 688, Sub-queries, true if any match
WITH t2 AS
(SELECT DISTINCT t2c
FROM
table2
)
SELECT t1.*
TABLE1
+-------+
|T1A|T1B|
|---|---|
|A |AA |
TABLE2
+-----------+
|T2A|T2B|T2C|
|---|---|---|
|A |A |A |
FROM
table1 t1
,t2
WHERE t1.t1a = t2.t2c;
|B |BB |
|C |CC |
+-------+
SELECT t1.*
FROM
table1 t1
,(SELECT DISTINCT t2c
FROM
table2
)AS t2
WHERE
t1.t1a = t2.t2c;
|B |A | - |
+-----------+
"-" = null
ANSWER
=======
T1A T1B
--- --A
AA
SELECT t1.*
FROM
table1 t1
INNER JOIN
(SELECT
DISTINCT t2c
FROM
table2
)AS t2
ON
t1.t1a = t2.t2c;
Figure 689, Joins, true if any match
SELECT *
FROM
table1 t1
WHERE 10 =
(SELECT
COUNT(*)
FROM
table2 t2
WHERE
t1.t1a = t2.t2b);
SELECT *
FROM
table1
WHERE EXISTS
(SELECT
FROM
WHERE
GROUP BY
HAVING
TABLE1
+-------+
|T1A|T1B|
|---|---|
|A |AA |
|B |BB |
|C |CC |
+-------+
t2b
table2
t1a = t2b
t2b
COUNT(*) = 10);
TABLE2
+-----------+
|T2A|T2B|T2C|
|---|---|---|
|A |A |A |
|B |A | - |
+-----------+
"-" = null
ANSWER
======
0 rows
SELECT *
FROM
table1
WHERE t1a IN
(SELECT
t2b
FROM
table2
GROUP BY t2b
HAVING
COUNT(*) = 10);
Figure 690, Sub-queries, true if ten match (1 of 2)
SELECT *
FROM
table1
WHERE (t1a,10) IN
(SELECT
t2b, COUNT(*)
FROM
table2
GROUP BY t2b);
Figure 691, Sub-queries, true if ten match (2 of 2)
ANSWER
======
0 rows
WITH t2 AS
(SELECT
t2b
FROM
table2
GROUP BY t2b
HAVING
COUNT(*) = 10
)
SELECT t1.*
FROM
table1 t1
,t2
WHERE t1.t1a = t2.t2b;
SELECT t1.*
FROM
table1 t1
,(SELECT
FROM
GROUP BY
HAVING
)AS t2
WHERE
t1.t1a =
TABLE1
+-------+
|T1A|T1B|
|---|---|
|A |AA |
|B |BB |
|C |CC |
+-------+
TABLE2
+-----------+
|T2A|T2B|T2C|
|---|---|---|
|A |A |A |
|B |A | - |
+-----------+
"-" = null
ANSWER
======
0 rows
t2b
table2
t2b
COUNT(*) = 10
t2.t2b;
SELECT t1.*
FROM
table1 t1
INNER JOIN
(SELECT
t2b
FROM
table2
GROUP BY t2b
HAVING
COUNT(*) = 10
)AS t2
ON
t1.t1a = t2.t2b;
Figure 692, Joins, true if ten match
SELECT *
FROM
table1
WHERE t1a = ALL
(SELECT t2b
FROM
table2);
SELECT *
FROM
table1
WHERE NOT EXISTS
(SELECT *
FROM
table2
WHERE t1a <> t2b);
TABLE1
+-------+
|T1A|T1B|
|---|---|
|A |AA |
|B |BB |
|C |CC |
+-------+
TABLE2
+-----------+
|T2A|T2B|T2C|
|---|---|---|
|A |A |A |
|B |A | - |
+-----------+
"-" = null
ANSWER
=======
T1A T1B
--- --A
AA
SELECT *
FROM
table1
WHERE t1a = ALL
(SELECT t2b
FROM
table2
WHERE t2b >= 'X');
ANSWER
=======
T1A T1B
--- --A
AA
B
BB
C
CC
SELECT *
FROM
table1
WHERE NOT EXISTS
(SELECT *
FROM
table2
WHERE t1a <> t2b
AND t2b >= 'X');
Figure 694, Sub-queries, true if all match, empty set
SELECT *
FROM
table1
WHERE t1a = ALL
(SELECT t2b
FROM
table2
WHERE t2b >= 'X')
AND 0 <>
(SELECT COUNT(*)
FROM
table2
WHERE t2b >= 'X');
TABLE1
+-------+
|T1A|T1B|
|---|---|
|A |AA |
|B |BB |
|C |CC |
+-------+
TABLE2
+-----------+
|T2A|T2B|T2C|
|---|---|---|
|A |A |A |
|B |A | - |
+-----------+
"-" = null
ANSWER
======
0 rows
SELECT *
FROM
table1
WHERE t1a IN
(SELECT MAX(t2b)
FROM
table2
WHERE t2b >= 'X'
HAVING COUNT(DISTINCT t2b) = 1);
Figure 695, Sub-queries, true if all match, and at least one value found
R1
UNION
R2
R1
-A
A
A
B
B
C
C
C
E
R2
-A
A
B
B
B
C
D
----A
B
C
D
E
R1
UNION
ALL
R2
----A
A
A
A
A
B
B
B
B
B
C
R1
INTERSECT
R2
--------A
B
C
R1
INTERSECT
ALL
R2
----A
A
B
B
C
R1
EXCEPT
R2
-----E
R1
EXCEPT
ALL
R2
-----A
C
C
E
C
C
C
D
E
Figure 696, Examples of Union, Except, and Intersect
CREATE VIEW
AS VALUES
CREATE VIEW
AS VALUES
R1 (R1)
('A'),('A'),('A'),('B'),('B'),('C'),('C'),('C'),('E');
R2 (R2)
('A'),('A'),('B'),('B'),('B'),('C'),('D');
ANSWER
======
SELECT
R1
R1 R2
FROM
R1
-- -ORDER BY R1;
A
A
A
A
SELECT
R2
A
B
FROM
R2
B
B
ORDER BY R2;
B
B
C
C
C
D
C
E
Figure 698, Query sample views
SELECT
FROM
UNION
SELECT
FROM
ORDER BY
R1
R1
R2
R2
1;
SELECT
R1
FROM
R1
UNION ALL
SELECT
R2
FROM
R2
ORDER BY 1;
R1
-A
A
A
B
B
C
C
C
E
R2
-A
A
B
B
B
C
D
UNION
=====
A
B
C
D
E
UNION ALL
=========
A
A
A
A
A
B
B
B
B
B
C
C
C
C
D
E
SELECT
R1
FROM
R1
INTERSECT
SELECT
R2
FROM
R2
ORDER BY 1;
R1
-A
A
A
B
B
C
C
C
E
R2
-A
A
B
B
B
C
D
INTERSECT
=========
A
B
C
SELECT
R1
FROM
R1
INTERSECT ALL
SELECT
R2
FROM
R2
ORDER BY 1;
Figure 700, Intersect and Intersect All SQL
SELECT
FROM
EXCEPT
SELECT
FROM
ORDER BY
R1
R1
R2
R2
1;
SELECT
R1
FROM
R1
EXCEPT ALL
SELECT
R2
FROM
R2
ORDER BY 1;
Figure 701,
SELECT
FROM
EXCEPT
SELECT
FROM
ORDER BY
R1 R2
-- -A
A
A
A
A
B
B
B
B
B
C
C
C
D
C
E
Except and Except All SQL (R1 on top)
R2
R2
R1
R1
1;
SELECT
R2
FROM
R2
EXCEPT ALL
SELECT
R1
FROM
R1
ORDER BY 1;
Figure 702,
R1 R2
-- -A
A
A
A
A
B
B
B
B
B
C
C
C
D
C
E
Except and Except All SQL (R2 on top)
INTERSECT ALL
=============
A
A
B
B
C
R1
EXCEPT
R2
=====
E
R1
EXCEPT ALL
R2
==========
A
C
C
E
R2
EXCEPT
R1
=====
D
R2
EXCEPT ALL
R1
==========
B
D
SELECT
FROM
UNION
SELECT
FROM
EXCEPT
SELECT
FROM
ORDER BY
ANSWER
======
E
R1
R1
R2
R2
R2
R2
1;
(SELECT
FROM
UNION
SELECT
FROM
)EXCEPT
SELECT
FROM
ORDER BY
R1
R1
R2
R2
R2
R2
1;
SELECT
FROM
UNION
(SELECT
FROM
EXCEPT
SELECT
FROM
)ORDER BY
R1
R1
R2
R2
R2
R2
1;
R1
-A
A
A
B
B
C
C
C
E
R2
-A
A
B
B
B
C
D
ANSWER
======
E
ANSWER
======
A
B
C
E
Figure 703, Use of parenthesis in Union
UPDATE sales_data
SET
amount = amount / 2
WHERE sales_rep = 'JOHN';
DELETE
FROM
WHERE
AND
Figure
sales_data
sales_date = '2003-01-01'
daily_seq# = 2;
705, Insert, update, and delete using view
ORIGINAL QUERY
OPTIMIZED QUERY
==============
=================================
SELECT
dept
SELECT Q1.dept AS "dept"
,AVG(id)
,Q1.sum_id / Q1.count_rows
FROM
staff
FROM
staff_summary AS Q1
GROUP BY dept
Figure 708, Original and optimized queries
REFRESH
=========
DEFERRED
MAINTAINED BY
REFRESH TABLE
INSERT/UPDATE/DELETE
=============
=============
====================
SYSTEM
yes
no
USER
no
yes
IMMEDIATE
SYSTEM
yes
no
Figure 710, Materialized query table options vs. allowable actions
SET CURRENT
SET CURRENT
SET CURRENT
Figure 713,
REFRESH AGE
0;
REFRESH AGE = ANY;
REFRESH AGE = 99999999999999;
Set refresh age command, examples
SET CURRENT
SET CURRENT
SET CURRENT
Figure 716,
MAINTAINED
TYPES
= ALL;
MAINTAINED TABLE TYPES
= SYSTEM;
MAINTAINED TABLE TYPES FOR OPTIMIZATION = USER, SYSTEM;
Set maintained type command, examples
MQT DEFINITION
DATABASE/APPLICATION STATUS
DB2
==========================
===================================
USE
REFRESH
MAINTAINED-BY
REFRESH-AGE
MAINTAINED-TYPE
MQT
=========
==============
===========
=====================
===
IMMEDIATE
SYSTEM
Yes
DEFERRED
SYSETM
ANY
ALL or SYSTEM
Yes
DEFERRED
USER
ANY
ALL or USER
Yes
DEFERRED
FEDERATED-TOOL
ANY
ALL or FEDERATED-TOOL
Yes
Figure 720, When DB2 will consider using a materialized query table
SELECT
count_rows
sum_salary
avg_salary
max_salary
min_salary
std_salary
var_salary
last_change
'%A%'
10000
SELECT
emp.workdept
,DEC(SUM(emp.salary),8,2)
AS sum_sal
,DEC(AVG(emp.salary),7,2)
AS avg_sal
,SMALLINT(COUNT(emp.comm)) AS #comms
,SMALLINT(COUNT(*))
AS #emps
FROM
employee emp
WHERE
emp.workdept
> 'C'
GROUP BY emp.workdept
HAVING
COUNT(*)
<> 5
AND
SUM(emp.salary) > 50000
ORDER BY sum_sal DESC;
Figure 724, Query that uses materialized query table (1 of 3)
SELECT
emp.workdept
,COUNT(*)
AS #rows
FROM
employee emp
WHERE
emp.workdept IN
(SELECT deptno
FROM
department
WHERE deptname LIKE '%S%')
GROUP BY emp.workdept
HAVING
SUM(salary) > 50000;
Figure 725, Query that uses materialized query table (2 of 3)
SELECT
FROM
#emps
,DEC(SUM(sum_sal),9,2)
,SMALLINT(COUNT(*))
(SELECT
emp.workdept
AS sal_sal
AS #depts
,DEC(SUM(emp.salary),8,2)
AS sum_sal
,MAX(emp.salary)
AS max_sal
,SMALLINT(COUNT(*))
AS #emps
FROM
employee emp
GROUP BY emp.workdept
)AS XXX
GROUP BY #emps
HAVING
COUNT(*) > 1
ORDER BY #emps
FETCH FIRST 3 ROWS ONLY
OPTIMIZE FOR 3 ROWS;
Figure 726, Query that uses materialized query table (3 of 3)
SELECT
emp.workdept
,DEC(SUM(emp.salary),8,2)
AS sum_sal
,MAX(emp.salary)
AS max_sal
FROM
employee emp
GROUP BY emp.workdept;
Figure 732, Query that doesn't use materialized query table (1 of 2)
SELECT
emp.workdept
,DEC(SUM(emp.salary),8,2)
AS sum_sal
,COUNT(DISTINCT salary)
AS #salaries
FROM
employee emp
GROUP BY emp.workdept;
Figure 733, Query that doesn't use materialized query table (2 of 2)
num_rows
num_salary
sum_salary
num_comm
sum_comm
FROM
employee
emp
,department dpt
WHERE
dpt.deptno = emp.workdept
GROUP BY emp.workdept
,dpt.deptname
)DATA INITIALLY DEFERRED REFRESH IMMEDIATE;
Figure 735, Multi-table materialized query table DDL
SELECT
d.deptname
,d.deptno
,DEC(AVG(e.salary),7,2)
AS avg_sal
,SMALLINT(COUNT(*))
AS #emps
FROM
department d
,employee
e
WHERE
e.workdept
= d.deptno
AND
d.deptname LIKE '%S%'
GROUP BY d.deptname
,d.deptno
HAVING
SUM(e.comm)
> 4000
ORDER BY avg_sal DESC;
Figure 736, Query that uses materialized query table
SELECT
FROM
Q2.$C0
,Q2.$C1
,Q2.$C2
,Q2.$C3
(SELECT
AS
AS
AS
AS
"deptname"
"deptno"
"avg_sal"
"#emps"
Q1.deptname
,Q1.workdept
,DEC((Q1.sum_salary / Q1.num_salary),7,2)
,SMALLINT(Q1.num_rows)
dept_emp_summary AS Q1
(Q1.deptname LIKE '%S%')
(4000 < Q1.sum_comm)
AS
AS
AS
AS
FROM
WHERE
AND
)AS Q2
ORDER BY Q2.$C2 DESC;
Figure 737, DB2 generated query to use materialized query table
$C0
$C1
$C2
$C3
AS
AS sum_time
AS num_time
AS num_rows
WHERE
dpt.deptno = emp.workdept
AND
emp.empno = act.empno
GROUP BY emp.workdept
,dpt.deptname
,emp.empno
,emp.firstnme
)DATA INITIALLY DEFERRED REFRESH IMMEDIATE;
Figure 738, Three-table materialized query table DDL
SELECT
d.deptno
,d.deptname
,DEC(AVG(a.emptime),5,2) AS avg_time
FROM
department d
,employee
e
,emp_act
a
WHERE
d.deptno
= e.workdept
AND
e.empno
= a.empno
AND
d.deptname LIKE '%S%'
AND
e.firstnme LIKE '%S%'
GROUP BY d.deptno
,d.deptname
ORDER BY 3 DESC;
Figure 739, Query that uses materialized query table
SELECT
Q4.$C0 AS "deptno"
,Q4.$C1 AS "deptname"
,Q4.$C2 AS "avg_time"
FROM
(SELECT
Q3.$C3
AS $C0
,Q3.$C2
AS $C1
,DEC((Q3.$C1 / Q3.$C0),5,2) AS $C2
FROM
(SELECT
SUM(Q2.$C2)
AS $C0
,SUM(Q2.$C3)
AS $C1
,Q2.$C0
AS $C2
,Q2.$C1
AS $C3
FROM
(SELECT
Q1.deptname
AS $C0
,Q1.workdept
AS $C1
,Q1.num_time
AS $C2
,Q1.sum_time
AS $C3
FROM
dpt_emp_act_sumry AS Q1
WHERE
(Q1.firstnme LIKE '%S%')
AND
(Q1.DEPTNAME LIKE '%S%')
)AS Q2
GROUP BY Q2.$C1
,Q2.$C0
)AS Q3
)AS Q4
ORDER BY Q4.$C2 DESC;
Figure 740, DB2 generated query to use materialized query table
SELECT
d.deptno
,d.deptname
,e.empno
,e.firstnme
,INT(AVG(a.emptime)) AS avg_time
FROM
department d
,employee
e
,emp_act
a
WHERE
d.deptno
= e.workdept
AND
e.empno
= a.empno
AND
d.deptno LIKE 'D%'
GROUP BY d.deptno
,d.deptname
,e.empno
,e.firstnme
ORDER BY 1,2,3,4;
Figure 742, Sample query that use WORKDEPT index
SELECT
d.deptno
,d.deptname
,e.empno
,e.firstnme
,COUNT(*)
AS #acts
FROM
department d
,employee
e
,emp_act
a
WHERE
d.deptno
= e.workdept
AND
e.empno
= a.empno
GROUP BY d.deptno
,d.deptname
,e.empno
,e.firstnme
HAVING
COUNT(*) > 4
ORDER BY 1,2,3,4;
Figure 743, Sample query that uses NUM_ROWS index
NULL
NULL
NULL
NULL
NULL
NULL
(START WITH
123
,MAXVALUE
124
,INCREMENT BY 0
,NO CYCLE
,NO ORDER)
,dat1 SMALLINT NOT NULL
,ts1
TIMESTAMP NOT NULL);
Figure 752, Identity column, dumb sequence
NULL
NULL
NULL
NULL
NULL
NULL
ANSWER
========
INVOICE#
-------101
102
INVOICE#
SALE_DATE
CUSTOMER_ID
PRODUCT_ID
----------------------------- -----100
2001-11-22
ABC
123
101
2002-11-22
DEF
123
102
2003-11-22
GHI
123
Figure 756, Invoice table, after inserts
QUANTITY
-------100
100
100
PRICE
----10.00
10.00
10.00
INVOICE#
SALE_DATE
CUSTOMER_ID
PRODUCT_ID
-----------------------------------100
2001-11-22
ABC
123
101
2002-11-22
DEF
123
102
2003-11-22
GHI
123
1000
2004-11-24
XXX
123
1002
2004-11-25
YYY
123
Figure 759, Invoice table, after second inserts
QUANTITY
-------100
100
100
100
100
PRICE
----10.00
10.00
10.00
10.00
10.00
,cname
,ctype
,PRIMARY KEY
COMMIT;
CHAR(10)
CHAR(03)
(cust#));
NOT NULL
NOT NULL
SELECT cust#
FROM
FINAL TABLE
(INSERT INTO customers
VALUES (DEFAULT,'FRED','XXX'));
ROLLBACK;
ANSWER
======
CUST#
----1
SELECT cust#
FROM
FINAL TABLE
(INSERT INTO customers
VALUES (DEFAULT,'FRED','XXX'));
COMMIT;
Figure 761, Gaps in Values, example
ANSWER
======
CUST#
----2
SELECT
MIN(cust#) AS minc
,MAX(cust#) AS maxc
,COUNT(*)
AS rows
FROM
FINAL TABLE
(INSERT INTO customers
VALUES (DEFAULT,'FRED','xxx')
,(DEFAULT,'DAVE','yyy')
,(DEFAULT,'JOHN','zzz'));
Figure 762, Selecting identity column values inserted
ANSWER
==============
MINC MAXC ROWS
---- ---- ---3
5
3
NULL
NULL
NULL
NULL
NULL
NULL
<<< ANSWER
======
ID
---1
<<< ANSWER
======
ID
----
invoice#
AS inv#
,sale_date
,IDENTITY_VAL_LOCAL() AS id
FROM
invoice_table
ORDER BY 1;
COMMIT;
Figure 764, IDENTITY_VAL_LOCAL function examples
SELECT invoice#
AS inv#
,sale_date
,IDENTITY_VAL_LOCAL() AS id
FROM
invoice_table
WHERE id = IDENTITY_VAL_LOCAL();
Figure 765, IDENTITY_VAL_LOCAL usage in predicate
ANSWER
==================
INV# SALE_DATE ID
---- ---------- -1 11/22/2000 2
2 11/23/2000 2
3 11/24/2000 2
4 11/25/2000 2
ANSWER
==================
INV# SALE_DATE ID
---- ---------- -2 11/23/2000 2
CYCLE;
Figure 767, Alter sequence attributes
ANSWER
======
SEQ#
---1
2
3
4
5
ANSWERS
=======
===>
PRV
---
===>
NXT
--1
===>
PRV
--1
===>
NXT PRV
--- --2
1
3
1
4
1
5
1
6
1
ANSWERS
=======
WITH temp1 AS
(SELECT
id
,NEXTVAL FOR fred AS nxt
FROM
staff
WHERE
id < 100
)
SELECT *
FROM
temp1
WHERE id = 50 + (nxt * 0);
===>
ID NXT
-- --50
5
===>
NXT PRV
--- --10
9
NOT
NOT
NOT
NOT
NULL
NULL
NULL
NULL
NOT
NOT
NOT
NOT
NULL
NULL
NULL
NULL
SELECT
cust#
,cname
FROM
FINAL TABLE
(INSERT INTO us_customer (cname, frst_sale, #sales)
VALUES ('FRED','2002-10-22',1)
,('JOHN','2002-10-23',1));
cust#
,cname
FROM
FINAL TABLE
(INSERT INTO intl_customer (cname, frst_sale, #sales)
VALUES ('SUE','2002-11-12',2)
,('DEB','2002-11-13',2));
Figure 773, Insert into tables with common sequence
ANSWERS
===========
CUST# CNAME
----- ----1 FRED
2 JOHN
SELECT
CUST#
----3
4
CNAME
----SUE
DEB
ANSWER
======
PREV
---4
ORDER;
CREATE TABLE customer
(cust#
INTEGER
,cname
CHAR(10)
,frst_sale
DATE
,#sales
INTEGER
,PRIMARY KEY
(cust#));
NOT
NOT
NOT
NOT
NULL
NULL
NULL
NULL
INSERT
INSERT
INSERT
Figure
INTO
INTO
INTO
781,
NOT NULL
NOT
NOT
NOT
NOT
NOT
NULL
NULL
NULL
NULL
NULL
SELECT
FROM
id
,salary
(SELECT
s.*
,ROW_NUMBER() OVER(ORDER BY salary DESC) AS sorder
FROM
staff s
WHERE
id < 200
ANSWER
)AS xxx
=============
WHERE
sorder BETWEEN 2 AND 3
ID
SALARY
ORDER BY id;
--- -------50 20659.80
140 21150.00
Figure 786, Nested Table Expression
(SELECT
ID
,salary
,ROW_NUMBER() OVER(ORDER BY salary DESC) AS sorder
FROM
staff
WHERE
id < 200
)
ANSWER
SELECT
id
=============
,salary
ID
SALARY
FROM
xxx
--- -------WHERE
sorder BETWEEN 2 AND 3
50 20659.80
ORDER BY id;
140 21150.00
Figure 787, Common Table Expression
WITH
ANSWER
rows_wanted AS
================================
(SELECT *
ID NAME
SALARY
SUM_SAL PCT
FROM
staff
-- ------- -------- -------- --WHERE
id
< 100
70 Rothman 16502.83 34504.58 47
AND
UCASE(name) LIKE '%T%'
90 Koonitz 18001.75 34504.58 52
),
sum_salary AS
(SELECT SUM(salary) AS sum_sal
FROM
rows_wanted)
SELECT
id
,name
,salary
,sum_sal
,INT((salary * 100) / sum_sal) AS pct
FROM
rows_wanted
,sum_salary
ORDER BY id;
Figure 788, Common Table Expression
COUNT(*) AS cnt
session.fred;
ANSWER#1
========
CNT
--4
ANSWER#2
==========================
DEPT AVG_SALARY NUM_EMPS
WHERE
SELECT *
FROM
session.fred;
Figure 789, Declared Global Temporary Table
---10
51
66
---------20168.08
15161.43
17215.24
-------3
3
5
WITH staff_dept AS
ANSWER
(SELECT
dept
AS dept#
==========================
,MAX(salary) AS max_sal
ID DEPT SALARY
MAX_SAL
FROM
staff
--- ---- -------- -------WHERE
dept < 50
10
20 18357.50 18357.50
GROUP BY dept
190
20 14252.75 18357.50
)
200
42 11508.60 18352.80
SELECT
id
220
51 17654.50
,dept
,salary
,max_sal
FROM
staff
LEFT OUTER JOIN
staff_dept
ON
dept
= dept#
WHERE
name LIKE 'S%'
ORDER BY id;
Figure 790, Identical query (1 of 3) - using Common Table Expression
SELECT
id
,dept
,salary
,max_sal
FROM
staff
LEFT OUTER JOIN
(SELECT
ANSWER
==========================
ID DEPT SALARY
MAX_SAL
--- ---- -------- -------10
20 18357.50 18357.50
190
20 14252.75 18357.50
200
42 11508.60 18352.80
220
51 17654.50
-
SELECT
ANSWER
==========================
ID DEPT SALARY
MAX_SAL
--- ---- -------- -------10
20 18357.50 18357.50
190
20 14252.75 18357.50
dept
AS dept#
,MAX(salary) AS max_sal
FROM
staff
WHERE
dept < 50
GROUP BY dept
)AS STAFF_dept
ON
dept
= dept#
WHERE
name LIKE 'S%'
ORDER BY id;
Figure 791, Identical query (2 of 3) - using full-select in FROM
id
,dept
,salary
,(SELECT
FROM
WHERE
MAX(salary)
staff s2
s1.dept = s2.dept
AND
s2.dept < 50
200
42 11508.60 18352.80
GROUP BY dept)
220
51 17654.50
AS max_sal
FROM
staff s1
WHERE
name LIKE 'S%'
ORDER BY id;
Figure 792, Identical query (3 of 3) - using full-select in SELECT
WITH temp1 AS
ANSWER
(SELECT MAX(name) AS max_name
==================
,MAX(dept) AS max_dept
MAX_NAME MAX_DEPT
FROM
staff
--------- -------)
Yamaguchi
84
SELECT *
FROM
temp1;
Figure 794, Common Table Expression, using named fields
WITH
temp1 AS
(SELECT
dept
,AVG(salary) AS avg_sal
FROM
staff
GROUP BY dept),
temp2 AS
(SELECT
MAX(avg_sal) AS max_avg
FROM
temp1)
SELECT *
FROM
temp2;
Figure 796, Query with two common table expressions
ANSWER
==========
MAX_AVG
---------20865.8625
SELECT *
ANSWER
FROM (SELECT MAX(avg_sal) AS max_avg
==========
FROM (SELECT dept
MAX_AVG
,AVG(salary) AS avg_sal
---------FROM
staff
20865.8625
GROUP BY dept
)AS temp1
)AS temp2;
Figure 797, Same as prior example, but using nested table expressions
WITH temp1 AS
(SELECT
id
,name
,dept
,salary
FROM
staff
WHERE
id
< 300
AND
dept
<> 55
AND
name LIKE 'S%'
AND
dept NOT IN
(SELECT deptnumb
FROM
org
WHERE division = 'SOUTHERN'
OR location = 'HARTFORD')
)
,temp2 AS
(SELECT
dept
,MAX(salary) AS max_sal
FROM
temp1
GROUP BY dept
)
SELECT
t1.id
,t1.dept
,t1.salary
,t2.max_sal
FROM
temp1 t1
,temp2 t2
WHERE
t1.dept = t2.dept
ORDER BY t1.id;
Figure 798, Deriving second temporary table
ANSWER
==========================
ID DEPT SALARY
MAX_SAL
--- ---- -------- -------10
20 18357.50 18357.50
190
20 14252.75 18357.50
200
42 11508.60 11508.60
220
51 17654.50 17654.50
from first
SELECT
division
,DEC(AVG(dept_avg),7,2) AS div_dept
,COUNT(*)
AS #dpts
,SUM(#emps)
AS #emps
FROM
(SELECT
division
,dept
,AVG(salary) AS dept_avg
,COUNT(*)
AS #emps
FROM
staff
ANSWER
,org
==============================
WHERE
dept = deptnumb
DIVISION DIV_DEPT #DPTS #EMPS
GROUP BY division
--------- -------- ----- ----,dept
Corporate 20865.86
1
4
)AS xxx
Eastern
15670.32
3
13
GROUP BY division;
Midwest
15905.21
2
9
Western
16875.99
2
9
Figure 801, Nested column function usage
SELECT id
FROM (SELECT *
FROM (SELECT id, years, salary
FROM (SELECT *
FROM
(SELECT *
FROM
staff
WHERE dept < 77
)AS t1
WHERE id < 300
)AS t2
WHERE job LIKE 'C%'
)AS t3
WHERE salary < 18000
)AS t4
WHERE years < 5;
Figure 802, Nested full-selects
SELECT
a.id
,a.dept
ANSWER
======
ID
--170
180
230
ANSWER
=========================
,a.salary
,DEC(b.avgsal,7,2) AS avg_dept
FROM
staff a
LEFT OUTER JOIN
(SELECT
dept
AS dept
,AVG(salary) AS avgsal
FROM
staff
GROUP BY dept
HAVING
AVG(salary) > 16000
)AS b
ON
a.dept = b.dept
WHERE
a.id
< 40
ORDER BY a.id;
Figure 803, Join full-select to real table
SELECT
a.id
ANSWER
,a.dept
=========================
,a.salary
ID DEPT SALARY
DEPTSAL
,b.deptsal
-- ---- -------- -------FROM
staff a
10 20
18357.50 64286.10
,TABLE
20 20
18171.25 64286.10
(SELECT
b.dept
30 38
17506.75 77285.55
,SUM(b.salary) AS deptsal
FROM
staff b
WHERE
b.dept = a.dept
GROUP BY b.dept
)AS b
WHERE
a.id
< 40
ORDER BY a.id;
Figure 804, Full-select with external table reference
SELECT
a.id
ANSWER
,a.dept
=========================
,a.salary
ID DEPT SALARY
DEPTSAL
,b.deptsal
-- ---- -------- -------FROM
staff a
10 20
18357.50 64286.10
,(SELECT
b.dept
20 20
18171.25 64286.10
,SUM(b.salary) AS deptsal
30 38
17506.75 77285.55
FROM
staff b
GROUP BY b.dept
)AS b
WHERE
a.id
< 40
AND
b.dept = a.dept
ORDER BY a.id;
Figure 805, Full-select without external table reference
SELECT
id
,salary
ANSWER
====================
,(SELECT MAX(salary)
FROM
staff
) AS maxsal
FROM
staff a
WHERE
id < 60
ORDER BY id;
ID SALARY
-- -------10 18357.50
20 18171.25
30 17506.75
40 18006.00
50 20659.80
Figure 806, Use an uncorrelated Full-Select in a SELECT list
MAXSAL
-------22959.20
22959.20
22959.20
22959.20
22959.20
SELECT
id
ANSWER
,salary
====================
,(SELECT MAX(salary)
ID SALARY
MAXSAL
FROM
staff b
-- -------- -------WHERE a.dept = b.dept
10 18357.50 18357.50
) AS maxsal
20 18171.25 18357.50
FROM
staff a
30 17506.75 18006.00
WHERE
id < 60
40 18006.00 18006.00
ORDER BY id;
50 20659.80 20659.80
Figure 807, Use a correlated Full-Select in a SELECT list
SELECT id
ANSWER
,dept
==================================
,salary
ID DEPT SALARY 4
5
,(SELECT MAX(salary)
-- ---- -------- -------- -------FROM
staff b
10
20 18357.50 18357.50 22959.20
WHERE b.dept = a.dept)
20
20 18171.25 18357.50 22959.20
,(SELECT MAX(salary)
30
38 17506.75 18006.00 22959.20
FROM
staff)
40
38 18006.00 18006.00 22959.20
FROM
staff a
50
15 20659.80 20659.80 22959.20
WHERE id < 60
ORDER BY id;
Figure 808, Use correlated and uncorrelated Full-Selects in a SELECT list
UPDATE staff a
SET
salary =
(SELECT AVG(salary)+ 2000
FROM
staff)
WHERE id < 60;
ANSWER:
SALARY
======= =================
ID DEPT BEFORE
AFTER
-- ---- -------- -------10
20 18357.50 18675.64
20
20 18171.25 18675.64
30
38 17506.75 18675.64
40
38 18006.00 18675.64
50
15 20659.80 18675.64
Figure 810, Use uncorrelated Full-Select to give workers company AVG salary (+$2000)
UPDATE staff a
SET
salary =
(SELECT AVG(salary) + 2000
FROM
staff b
WHERE a.dept = b.dept )
WHERE id < 60;
ANSWER:
SALARY
======= =================
ID DEPT BEFORE
AFTER
-- ---- -------- -------10
20 18357.50 18071.52
20
20 18171.25 18071.52
30
38 17506.75 17457.11
40
38 18006.00 17457.11
50
15 20659.80 17482.33
Figure 811, Use correlated Full-Select to give workers department AVG salary (+
$2000)
UPDATE staff a
SET
(salary,years) =
(SELECT AVG(salary) + 2000
,MAX(years)
FROM
staff b
WHERE a.dept = b.dept )
WHERE id < 60;
Figure 812, Update two fields by referencing Full-Select
COUNT(*)
session.fred;
COMMIT;
SELECT COUNT(*)
FROM
session.fred;
Figure 817, Temporary table with index
ANSWER
======
19
ANSWER
======
0
ANSWER
======
8
COUNT(*)
session.fred;
ANSWER
======
0
SELECT COUNT(*)
FROM
session.fred;
Figure 818, Dropping a temporary table
HIERARCHY
+---------------+
|PKEY |CKEY |NUM|
|-----|-----|---|
|AAA |BBB | 1|
|AAA |CCC | 5|
|AAA |DDD | 20|
|CCC |EEE | 33|
|DDD |EEE | 44|
|DDD |FFF | 5|
|FFF |GGG | 5|
+---------------+
Figure 820, Sample Table description - Recursion
AAA
|
+-----+-----+
|
|
|
BBB
CCC
DDD
|
|
+-+ +-+--+
| |
|
EEE
FFF
|
|
GGG
ANSWER
=========
PKEY CKEY
PROCESSING
SEQUENCE
---AAA
AAA
AAA
CCC
DDD
DDD
FFF
---BBB
CCC
DDD
EEE
EEE
FFF
GGG
==========
< 1st pass
""
""
< 2nd pass
< 3rd pass
""
< 4th pass
ANSWER
======
CKEY
---BBB
CCC
DDD
EEE
EEE
FFF
GGG
HIERARCHY
+---------------+
|PKEY |CKEY |NUM|
|-----|-----|---|
|AAA |BBB | 1|
|AAA |CCC | 5|
|AAA |DDD | 20|
|CCC |EEE | 33|
|DDD |EEE | 44|
|DDD |FFF | 5|
|FFF |GGG | 5|
FROM
parent;
Figure 824, List of children of AAA
+---------------+
ANSWER
======
CKEY
---AAA
BBB
CCC
DDD
EEE
EEE
FFF
GGG
HIERARCHY
+---------------+
|PKEY |CKEY |NUM|
|-----|-----|---|
|AAA |BBB | 1|
|AAA |CCC | 5|
|AAA |DDD | 20|
|CCC |EEE | 33|
|DDD |EEE | 44|
|DDD |FFF | 5|
|FFF |GGG | 5|
+---------------+
ANSWER
======
CKEY
---AAA
BBB
CCC
DDD
EEE
FFF
GGG
HIERARCHY
+---------------+
|PKEY |CKEY |NUM|
|-----|-----|---|
|AAA |BBB | 1|
|AAA |CCC | 5|
|AAA |DDD | 20|
|CCC |EEE | 33|
|DDD |EEE | 44|
|DDD |FFF | 5|
|FFF |GGG | 5|
+---------------+
ANSWER
======
CKEY
---AAA
BBB
CCC
DDD
EEE
FFF
GGG
HIERARCHY
+---------------+
|PKEY |CKEY |NUM|
|-----|-----|---|
|AAA |BBB | 1|
|AAA |CCC | 5|
|AAA |DDD | 20|
|CCC |EEE | 33|
|DDD |EEE | 44|
|DDD |FFF | 5|
|FFF |GGG | 5|
+---------------+
ANSWER
========
CKEY LVL
---- --AAA
0
BBB
1
CCC
1
DDD
1
EEE
2
EEE
2
FFF
2
GGG
3
ANSWER
========
CKEY LVL
---- --AAA
0
BBB
1
CCC
1
DDD
1
EEE
2
EEE
2
FFF
2
ANSWER
========
CKEY LVL
---- --AAA
0
BBB
1
CCC
1
DDD
1
EEE
2
EEE
2
FFF
2
AAA
|
+-----+-----+
|
|
|
BBB
CCC
DDD
|
|
+-+ +-+--+
| |
|
EEE
FFF
|
|
GGG
HIERARCHY
+---------------+
|PKEY |CKEY |NUM|
|-----|-----|---|
|AAA |BBB | 1|
|AAA |CCC | 5|
|AAA |DDD | 20|
|CCC |EEE | 33|
|DDD |EEE | 44|
|DDD |FFF | 5|
|FFF |GGG | 5|
+---------------+
AAA
|
+-----+-----+
|
|
|
BBB
CCC
DDD
|
|
+-+ +-+--+
| |
|
EEE
FFF
|
|
GGG
ANSWER
========
CKEY LVL
---- --EEE
2
EEE
2
FFF
2
HIERARCHY
+---------------+
|PKEY |CKEY |NUM|
|-----|-----|---|
|AAA |BBB | 1|
|AAA |CCC | 5|
|AAA |DDD | 20|
|CCC |EEE | 33|
|DDD |EEE | 44|
|DDD |FFF | 5|
|FFF |GGG | 5|
+---------------+
AAA
|
+-----+-----+
|
|
|
BBB
CCC
DDD
|
|
+-+ +-+--+
| |
|
EEE
FFF
|
|
GGG
ANSWER
======
N1
-warn
10
20
30
)
SELECT *
FROM
temp1;
Figure 833, Recursion - with warning message
40
50
DIVERGENT
=========
CONVERGENT
==========
RECURSIVE
=========
AAA
AAA
AAA<--+
|
|
|
|
+-+-+
+-+-+
+-+-+ |
|
|
|
|
|
| |
BBB CCC
BBB CCC
BBB CCC>+
|
|
|
|
+-+-+
+-+-+-+
+-+-+
|
|
|
|
|
|
DDD EEE
DDD EEE
DDD EEE
Figure 835, Hierarchy Flavours
ANSWER
======
N1
-10
20
30
40
50
BALANCED
========
AAA
|
+-+-+
|
|
BBB CCC
|
|
|
+---+
|
|
|
DDD EEE FFF
OBJECTS_RELATES
+---------------------+
|KEYO |PKEY |NUM|PRICE|
|-----|-----|---|-----|
|AAA |
|
| $10|
|BBB |AAA | 1| $21|
|CCC |AAA | 5| $23|
|DDD |AAA | 20| $25|
|EEE |DDD | 44| $33|
|FFF |DDD | 5| $34|
|GGG |FFF | 5| $44|
+---------------------+
Figure 836, Divergent Hierarchy - Table and Layout
UNBALANCED
==========
AAA
|
+-+-+
|
|
BBB CCC
|
+-+-+
|
|
DDD EEE
AAA
|
+-----+-----+
|
|
|
BBB
CCC
DDD
|
+--+--+
|
|
EEE
FFF
|
|
GGG
OBJECTS
RELATIONSHIPS
AAA
+-----------+
+---------------+
|
|KEYO |PRICE|
|PKEY |CKEY |NUM|
+-----+-----+
|-----|-----|
|-----|-----|---|
|
|
|
|AAA | $10|
|AAA |BBB | 1|
BBB
CCC
DDD
|BBB | $21|
|AAA |CCC | 5|
|
|
|CCC | $23|
|AAA |DDD | 20|
+-+ +-+--+
|DDD | $25|
|CCC |EEE | 33|
| |
|
|EEE | $33|
|DDD |EEE | 44|
EEE
FFF
|FFF | $34|
|DDD |FFF | 5|
|
|GGG | $44|
|FFF |GGG | 5|
|
+-----------+
+---------------+
GGG
Figure 837, Convergent Hierarchy - Tables and Layout
OBJECTS
+-----------+
|KEYO |PRICE|
|-----|-----|
|AAA | $10|
|BBB | $21|
|CCC | $23|
|DDD | $25|
|EEE | $33|
|FFF | $34|
|GGG | $44|
+-----------+
RELATIONSHIPS
AAA <------+
+---------------+
|
|
|PKEY |CKEY |NUM|
+-----+-----+
|
|-----|-----|---|
|
|
|
|
|AAA |BBB | 1|
BBB
CCC
DDD>-+
|AAA |CCC | 5|
|
|
|AAA |DDD | 20|
+-+ +-+--+
|CCC |EEE | 33|
| |
|
|DDD |AAA | 99|
EEE
FFF
|DDD |FFF | 5|
|
|DDD |EEE | 44|
|
|FFF |GGG | 5|
GGG
+---------------+
Figure 838, Recursive Hierarchy - Tables and Layout
AAA
|
+-----+-----+
|
|
|
BBB
CCC
DDD
|
|
|
|
|
+-+-+
|
|
|
|
EEE
FFF GGG HHH
AAA
|
+---+----+
|
|
|
| CCC DDD
|
|
|
| +-+ +-+-+
| |
|
|
FFF
GGG HHH
|
|
III
TROUBLE
+---------+
AAA <------+
|
|
|PKEY|CKEY|
+-----+-----+
|
|----|----|
|
|
|
|
|AAA |BBB |
BBB
CCC
DDD>-+
|AAA |CCC |
|
|
|AAA |DDD |
+-+ +-+--+
|CCC |EEE |
| |
|
|DDD |AAA |
<=== This row
EEE
FFF
|DDD |FFF |
points back to
|
|DDD |EEE |
the hierarchy
|
|FFF |GGG |
parent.
GGG
+---------+
Figure 840, Recursive Hierarchy - Sample Table and Layout
NOT NULL
NOT NULL);
TROUBLE
+---------+
|PKEY|CKEY|
|----|----|
|AAA |BBB |
|AAA |CCC |
|AAA |DDD |
|CCC |EEE |
|DDD |AAA |
|DDD |FFF |
|DDD |EEE |
|FFF |GGG |
+---------+
SELECT id
,name
,LOCATE('th',name)
AS l1
,LOCATE_BLOCK('th',name) AS l2
FROM
staff
WHERE LOCATE('th',name) > 1;
Figure 844, LOCATE_BLOCK function example
ANSWER
=================
ID NAME
L1 L2
--- ------- -- -70 Rothman 3 2
220 Smith
4 0
FFF
GGG
TROUBLE
+---------+
|PKEY|CKEY|
|----|----|
|AAA |BBB |
|AAA |CCC |
|AAA |DDD |
|CCC |EEE |
|DDD |AAA |
|DDD |FFF |
|DDD |EEE |
|FFF |GGG |
+---------+
3 AAADDDFFFGGG
AAA <------+
|
|
+-----+-----+
|
|
|
|
|
BBB
CCC
DDD>-+
|
|
+-+ +-+--+
| |
|
EEE
FFF
|
|
GGG
,P.path || C.ckey
,LOCATE_BLOCK(C.ckey,P.path)
FROM
trouble C
,parent P
WHERE P.ckey = C.pkey
AND P.loop = 0
CCC
DDD
DDD
DDD
FFF
EEE
AAA
EEE
FFF
GGG
2
2
2
2
3
AAACCCEEE
AAADDDAAA
AAADDDEEE
AAADDDFFF
AAADDDFFFGGG
0
1
0
0
0
)
SELECT *
FROM
parent;
Figure 847, Use LOCATE_BLOCK function to stop recursion
AS
ANSWER
=========
PKEY CKEY
---- ---DDD AAA
TROUBLE
+---------+
|PKEY|CKEY|
|----|----|
|AAA |BBB |
|AAA |CCC |
|AAA |DDD |
|CCC |EEE |
|DDD |AAA |
|DDD |FFF |
|DDD |EEE |
|FFF |GGG |
+---------+
parent
TROUBLE
+---------+
|PKEY|CKEY|
|----|----|
|AAA |BBB |
|AAA |CCC |
SELECT C.pkey
,C.ckey
,P.lvl + 1
,P.path || C.ckey
,LOCATE_BLOCK(C.ckey,P.path)
FROM
trouble C
,parent P
WHERE P.ckey = C.pkey
AND P.loop = 0
)
SELECT pkey
,ckey
FROM
parent
WHERE loop > 0;
DELETE
FROM
trouble
WHERE (pkey,ckey) IN
(SELECT pkey, ckey
FROM
SESSION.del_list);
Figure 849, Delete rows that loop back to a parent
AAA <------+
|
|
+-----+-----+
|
|
|
|
|
BBB
CCC
DDD>-+
|
|
+-+ +-+--+
| |
|
EEE
FFF
|
|
GGG
|AAA |DDD |
|CCC |EEE |
|DDD |AAA |
|DDD |FFF |
|DDD |EEE |
|FFF |GGG |
+---------+
TROUBLE
+---------+
|PKEY|CKEY|
|----|----|
|AAA |BBB |
|AAA |CCC |
|AAA |DDD |
|CCC |EEE |
|DDD |AAA |
|DDD |FFF |
|DDD |EEE |
|FFF |GGG |
+---------+
,CASE
WHEN TTT.ckey = TBL.pkey
THEN RAISE_ERROR('70001','LOOP FOUND')
ELSE TBL.ckey
END
FROM
trouble TBL
,temp
TTT
WHERE TTT.ckey = TBL.pkey
)
SELECT *
FROM
temp;
Figure 851, UPDATE trigger
EXPLODED#1
+-------------+
|PKEY|CKEY|LVL|
|----|----|---|
|AAA |AAA | 0|
|AAA |BBB | 1|
|AAA |CCC | 2|
|AAA |DDD | 3|
|AAA |EEE | 2|
|BBB |BBB | 0|
|BBB |CCC | 1|
|BBB |DDD | 2|
|BBB |EEE | 1|
|CCC |CCC | 0|
|CCC |DDD | 1|
|DDD |DDD | 0|
|EEE |EEE | 0|
+-------------+
Figure 853, Data Hierarchy, with normalized and exploded representations
AAA
|
BBB
|
+-----+
|
|
CCC
EEE
|
DDD
HIERARCHY#1
+--------------------+
|KEYY|PKEY|DATA
|
|----|----|----------|
|AAA |AAA |SOME DATA |
|BBB |AAA |MORE DATA |
|CCC |BBB |MORE JUNK |
|DDD |CCC |MORE JUNK |
|EEE |BBB |JUNK DATA |
+--------------------+
SELECT
FROM
WHERE
ORDER BY
*
exploded#1
pkey = :host-var
pkey
,ckey
,lvl;
Figure 858, Querying the exploded table
FROM
WHERE
exploded#2
ckey IN
(SELECT ckey
FROM
exploded#2
WHERE pkey = OOO.keyy);
INSERT
INTO
exploded#2
WITH temp1(ckey) AS
(VALUES (NNN.keyy)
UNION ALL
SELECT N.keyy
FROM
temp1
T
,hierarchy#2 N
WHERE
N.pkey = T.ckey
AND
N.pkey <> N.keyy
)
Figure 864, Trigger to run after update of PKEY in hierarchy table (part 1 of 2)
END
Figure 865, Trigger to run after update of PKEY in hierarchy table (part 2 of 2)
SELECT
FROM
WHERE
ORDER BY
*
exploded#2
pkey = :host-var
pkey
,ckey
,lvl;
Figure 866, Querying the exploded table
NOT NULL
AS IDENTITY
NOT NULL
NOT NULL
NOT NULL
NOT NULL
cust_history
INTEGER
NOT
INTEGER
NOT
DECIMAL(18,2)
NOT
TIMESTAMP
NOT
TIMESTAMP
NOT
(cust#, bgn_ts));
NULL
NULL
NULL
NULL
NULL
NOT NULL
NOT NULL
NOT NULL
DECIMAL(nnn.sale_value)
WHERE ccc.cust_id
= nnn.cust_id;
Figure 892, Propagate change to Customer-Balance table
NOT NULL
NULL
NULL
NULL
NULL
,(SELECT
FROM
WHERE
Figure 899,
MAX(cur_ts)
customer_his hhh
ooo.cust# = hhh.cust#));
Update trigger
NOT NULL
NOT NULL DEFAULT '9999-12-31-24.00.00'
WHERE
ppp.user_id
= USER
AND
hhh.cur_actn <> 'D'
AND ((ppp.vrsn
= 0
AND
hhh.cur_vrsn
= 0)
OR (ppp.vrsn
> 0
AND
hhh.cur_vrsn
= 0
AND
hhh.cur_ts
< ppp.vrsn_bgn_ts)
OR (ppp.vrsn
> 0
AND
hhh.cur_vrsn
= ppp.vrsn))
AND
NOT EXISTS
(SELECT *
FROM
customer_his nnn
WHERE
nnn.prv_cust# = hhh.cust#
AND
nnn.prv_ts
= hhh.cur_ts
AND
nnn.prv_vrsn
= hhh.cur_vrsn
AND ((ppp.vrsn
= 0
AND
nnn.cur_vrsn
= 0)
OR (ppp.vrsn
> 0
AND
nnn.cur_vrsn
= 0
AND
nnn.cur_ts
< ppp.vrsn_bgn_ts)
OR (ppp.vrsn
> 0
AND
nnn.cur_vrsn
= ppp.vrsn)));
Figure 906, Customer view - 1 of 2
,NULL
,NULL
,NULL);
Figure 908, Insert trigger
SELECT
SELECT
'SELECT '''
CONCAT
tabname
CONCAT
''', COUNT(*) FROM '
CONCAT
RTRIM(tabschema)
CONCAT
'.'
CONCAT
tabname
CONCAT
';'
FROM
syscat.tables
WHERE
tabschema
= 'SYSCAT'
AND
tabname
LIKE 'N%'
ORDER BY tabschema
,tabname;
ANSWER
==========================================================
SELECT 'NAMEMAPPINGS', COUNT(*) FROM SYSCAT.NAMEMAPPINGS;
SELECT 'NODEGROUPDEF', COUNT(*) FROM SYSCAT.NODEGROUPDEF;
SELECT 'NODEGROUPS', COUNT(*) FROM SYSCAT.NODEGROUPS;
Figure 913, Generate SQL to count rows
SELECT SUM(C1)
FROM (
SELECT COUNT(*) AS C1 FROM SYSCAT.NAMEMAPPINGS UNION ALL
SELECT COUNT(*) AS C1 FROM SYSCAT.NODEGROUPDEF UNION ALL
SELECT COUNT(*) AS C1 FROM SYSCAT.NODEGROUPS
) AS xxx;
Figure 915, Generate SQL to count rows (all tables)
tabschema
,tabname
,ROW_NUMBER() OVER(ORDER BY tabschema
,tabname
,ROW_NUMBER() OVER(ORDER BY tabschema
,tabname
FROM
syscat.tables
WHERE
tabschema LIKE in_tabschema
AND
tabname
LIKE in_tabname
ORDER BY tabschema ASC
,tabname
ASC
WITH UR
ASC
ASC) AS aa
DESC
DESC) AS dd
DO
IF aa = 1 THEN
SET stmt = 'SELECT SUM(c1) FROM (';
END IF;
SET stmt = stmt || 'SELECT COUNT(*) AS c1 FROM '
|| RTRIM(tabschema)
|| '.'
|| tabname;
IF dd > 1 THEN
SET stmt = stmt || ' UNION ALL ';
ELSE
SET stmt = stmt || ' ) AS xxx WITH UR ';
END IF;
END FOR;
PREPARE s1 FROM stmt;
OPEN c1;
END
Figure 916, Count rows in all matching tables
ANSWERS
=======
9848
5
0
CALL CountRows('SYSCAT%','%');
CALL CountRows('SYSCAT%','N%');
CALL CountRows('SYSCAT%','Z%');
Figure 917, Run procedure
tabschema
,tabname
FROM
syscat.tables
WHERE
tabschema LIKE
AND
tabname
LIKE
ORDER BY tabschema ASC
,tabname
ASC
WITH UR
in_tabschema
in_tabname
DO
END
Figure 918, Count rows in all matching tables
ANSWERS
===================
NUM_ROWS NUM_TABLES
-------- ---------9867
100
5
3
0
0
CALL CountRows('SYSCAT%','%');
CALL CountRows('SYSCAT%','N%');
CALL CountRows('SYSCAT%','Z%');
Figure 919, Run procedure
FROM
in_tabschema
in_tabname
tabschema
,tabname
session.tab_list
||
||
||
||
||
||
||
||
|| tabschema || '''' ||
|| tabname
|| '''' ;
OPEN c1;
END;
END
Figure 920, Count rows in each matching table
ANSWER
======
COL1
---0
1
2
3
etc
SELECT *
FROM
TABLE(NumList(100)) AS xxx;
Figure 922, Use user-defined-function to get list of 100 numbers
ANSWER
============
SEQ#
RAN1
---- ----0 0.001
1 0.563
2 0.193
3 0.808
4 0.585
ANSWER
========================
SEQ# RAN2 RAN1
RAN3
---- ---- ------ ---0
13 0.0013
0
1 8916 0.8916
8
2 7384 0.7384
7
3 5430 0.5430
5
4 8998 0.8998
8
,SMALLINT(r1*10)
AS ran3
FROM
temp1;
Figure 924, Make differing ranges of random numbers
ANSWER
=======================
S#
RAN1
RAN2
RAN3
-- ------ ------ -----0
1251 365370 114753
1 350291 280730 88106
2 710501 149549 550422
3 147312 33311
2339
4
8911
556 73091
WITH
temp1 (s1) AS
(VALUES (0)
UNION ALL
SELECT s1 + 1
FROM
temp1
WHERE s1 + 1
< 5
)
SELECT SMALLINT(s1)
AS s#
,INTEGER((RAND(1))
* 1E6) AS ran1
,INTEGER((RAND() * RAND())
* 1E6) AS ran2
,INTEGER((RAND() * RAND()* RAND()) * 1E6) AS ran3
FROM
temp1;
Figure 925, Create RAND data with different distributions
seq#
ran2
ran3
ran4
ANSWER
===================
SEQ# RAN2 RAN3 RAN4
---- ---- ---- ---0
65 A
65
1
88 X
88
2
84 T
84
3
79 O
79
4
88 X
88
0)
0)
,CONSTRAINT
,CONSTRAINT
,CONSTRAINT
,CONSTRAINT
,CONSTRAINT
,CONSTRAINT
,CONSTRAINT
,CONSTRAINT
pe03
pe04
pe05
pe06
pe07
pe08
pe09
pe10
CHECK
CHECK
CHECK
CHECK
CHECK
CHECK
CHECK
CHECK
(LOCATE('-',socsec#,1) = 4)
(LOCATE('-',socsec#,5) = 7)
(job_ftn
<> '')
(dept
BETWEEN 1 AND
99)
(salary BETWEEN 0 AND 99999)
(fst_name
<> '')
(lst_name
<> '')
(date_bn >= '1900-01-01' ));
EMP#
------
SOCSEC#
JOB_ DEPT SALARY
DATE_BN
F_NME
L_NME
----------- ---- ---- --------- ---------- --------- ---------
1979-01-01 Ammaef
1962-04-10 Ilojff
1975-01-03 Xzacaa
1971-02-05 Lpiedd
1979-01-01 Wgfacc
1977-01-02 Wrebbc
1979-01-01 Mobaaa
1968-03-07 Emjgdd
1974-02-03 Jnbcaa
Sample Output
Mimytmbi
Liiiemea
Zytaebma
Pimmeeat
Geimteei
Rbiybeet
Oiiaiaia
Mimtmamb
Nieebayt
SELECT kyy
,bgn_dt
,end_dt
FROM
time_series a
WHERE EXISTS
(SELECT *
FROM
time_series b
WHERE a.kyy
= b.kyy
AND a.bgn_dt <> b.bgn_dt
AND (a.bgn_dt BETWEEN b.bgn_dt AND b.end_dt
OR b.bgn_dt BETWEEN a.bgn_dt AND a.end_dt))
ORDER BY 1,2;
Figure 932, Find overlapping rows in time-series
ANSWER
=========
SELECT a.kyy
,a.bgn_dt
,a.end_dt
,b.bgn_dt
,b.end_dt
,DAYS(b.bgn_dt) DAYS(A.end_dt)
as diff
FROM
time_series a
,time_series b
WHERE a.kyy
= b.kyy
AND a.end_dt < b.bgn_dt - 1 DAY
AND NOT EXISTS
(SELECT *
FROM
time_series z
WHERE z.kyy
= a.kyy
AND z.kyy
= b.kyy
AND z.bgn_dt > a.bgn_dt
AND z.bgn_dt < b.bgn_dt)
ORDER BY 1,2;
Figure 933, Find gap in Time-Series, SQL
TIME_SERIES
+-------------------------+
|KYY|BGN_DT
|END_DT
|
|---|----------|----------|
|AAA|1995-10-01|1995-10-04|
|AAA|1995-10-06|1995-10-06|
|AAA|1995-10-07|1995-10-07|
|AAA|1995-10-15|1995-10-19|
|BBB|1995-10-01|1995-10-01|
|BBB|1995-10-03|1995-10-03|
+-------------------------+
KEYCOL BGN_DT
END_DT
BGN_DT
------ ---------- ---------- ---------AAA
1995-10-01 1995-10-04 1995-10-06
AAA
1995-10-07 1995-10-07 1995-10-15
BBB
1995-10-01 1995-10-01 1995-10-03
Figure 934, Find gap in Time-Series, Answer
SELECT a.kyy
AS kyy
,a.end_dt + 1 DAY
AS bgn_gap
,b.bgn_dt - 1 DAY
AS end_gap
,(DAYS(b.bgn_dt) DAYS(a.end_dt) - 1) AS sz
FROM
time_series a
,time_series b
WHERE a.kyy
= b.kyy
AND a.end_dt < b.bgn_dt - 1 DAY
AND NOT EXISTS
(SELECT *
FROM
time_series z
WHERE z.kyy
= a.kyy
AND z.kyy
= b.kyy
AND z.bgn_dt > a.bgn_dt
AND z.bgn_dt < b.bgn_dt)
ORDER BY 1,2;
Figure 935, Find gap in Time-Series
END_DT
---------1995-10-06
1995-10-19
1995-10-03
DIFF
---2
8
2
TIME_SERIES
+-------------------------+
|KYY|BGN_DT
|END_DT
|
|---|----------|----------|
|AAA|1995-10-01|1995-10-04|
|AAA|1995-10-06|1995-10-06|
|AAA|1995-10-07|1995-10-07|
|AAA|1995-10-15|1995-10-19|
|BBB|1995-10-01|1995-10-01|
|BBB|1995-10-03|1995-10-03|
+-------------------------+
ANSWER
============================
KYY BGN_GAP
END_GAP
SZ
--- ---------- ---------- -AAA 1995-10-05 1995-10-05 1
AAA 1995-10-08 1995-10-14 7
BBB 1995-10-02 1995-10-02 1
WITH temp
TIME_SERIES
(kyy, gap_dt, gsize) AS
+-------------------------+
(SELECT a.kyy
|KYY|BGN_DT
|END_DT
|
,a.end_dt + 1 DAY
|---|----------|----------|
,(DAYS(b.bgn_dt) |AAA|1995-10-01|1995-10-04|
DAYS(a.end_dt) - 1)
|AAA|1995-10-06|1995-10-06|
FROM
time_series a
|AAA|1995-10-07|1995-10-07|
,time_series b
|AAA|1995-10-15|1995-10-19|
WHERE a.kyy
= b.kyy
|BBB|1995-10-01|1995-10-01|
AND a.end_dt < b.bgn_dt - 1 DAY
|BBB|1995-10-03|1995-10-03|
AND NOT EXISTS
+-------------------------+
(SELECT *
FROM
time_series z
WHERE z.kyy
= a.kyy
AND z.kyy
= b.kyy
ANSWER
AND z.bgn_dt > a.bgn_dt
=======================
AND z.bgn_dt < b.bgn_dt)
KEYCOL GAP_DT
GSIZE
UNION ALL
------ ---------- ----SELECT kyy
AAA
1995-10-05
1
,gap_dt + 1 DAY
AAA
1995-10-08
7
,gsize - 1
AAA
1995-10-09
6
FROM
temp
AAA
1995-10-10
5
WHERE gsize > 1
AAA
1995-10-11
4
)
AAA
1995-10-12
3
SELECT
*
AAA
1995-10-13
2
FROM
temp
AAA
1995-10-14
1
ORDER BY 1,2;
BBB
1995-10-02
1
Figure 936, Show each day in Time-Series gap
SELECT
*
FROM
staff TABLESAMPLE BERNOULLI(5) REPEATABLE(1234)
ORDER BY id;
Figure 938, Sample rows in STAFF table
SELECT
FROM
*
employee ee TABLESAMPLE BERNOULLI(18)
,emp_act ea TABLESAMPLE BERNOULLI(25)
WHERE
ee.empno = ea.empno
ORDER BY ee.empno;
Figure 939, Sample rows in two tables
INPUT STRING
COMPATIBLE FUNCTIONS
============
==========================================
"
1234"
DOUBLE, DECIMAL, INTEGER, SMALLINT, BIGINT
"
12.4"
DOUBLE, DECIMAL
"
12E4"
DOUBLE
Figure 942, Acceptable conversion values
--#SET DELIMITER !
IMPORTANT
============
This example
uses an "!"
as the stmt
delimiter.
SELECT
ANSWER
====================
C1
C2 C3
------- -- --------123 Y 123.00000
+123.45 Y 123.45000
456
N
10 2
N
-.23 Y
-0.23000
++12356 N
.012349 Y
0.01234
33% N
N
-
d_sal
,CHAR(d_sal)
AS d_chr
,DIGITS(d_sal) AS d_dgt
,i_sal
,CHAR(i_sal)
AS i_chr
,DIGITS(i_sal) AS i_dgt
FROM
(SELECT DEC(salary - 11000,6,2) AS d_sal
,SMALLINT(salary - 11000) AS i_sal
FROM
staff
WHERE
salary > 10000
AND
salary < 12200
)AS xxx
ANSWER
ORDER BY d_sal;
=========================================
D_SAL
D_CHR
D_DGT I_SAL I_CHR I_DGT
-------494.10
-12.00
508.60
1009.75
Figure 946, CHAR and DIGITS function
--------0494.10
-0012.00
0508.60
1009.75
usage
----00494
00012
00508
01009
SELECT
i_sal
,char_right(i_sal) AS i_chr
FROM
(SELECT SMALLINT(salary - 11000) AS i_sal
FROM
staff
WHERE
salary > 10000
AND
salary < 12200
)AS xxx
ORDER BY i_sal;
Figure 948, Convert SMALLINT to CHAR
ANSWER
===========
I_SAL I_CHR
----- -----494 -494
-12
-12
508
508
1009 1009
SELECT
FROM
d_sal
,char_right(d_sal)
AS d_chr
(SELECT DEC(salary - 11000,6,2)
FROM
staff
AS d_sal
WHERE
AND
)AS xxx
ORDER BY d_sal;
ANSWER
===============
D_SAL
D_CHR
------- -------494.10 -494.10
-12.00 -12.00
508.60 508.60
1009.75 1009.75
WITH
ANSWER
temp1 (num) AS
====================================
(VALUES (DEC(+1,20,2))
INPUT
OUTPUT
,(DEC(-1,20,2))
----------------- -----------------UNION ALL
-975460660753.97 -975,460,660,753.97
SELECT num * 987654.12
-987655.12
-987,655.12
FROM
temp1
-2.00
-2.00
WHERE
ABS(num) < 1E10),
0.00
0.00
temp2 (num) AS
987653.12
987,653.12
(SELECT num - 1
975460660751.97 975,460,660,751.97
FROM
temp1)
SELECT
num
AS input
,comma_right(num) AS output
FROM
temp2
ORDER BY num;
WITH tab1(ts1) AS
(VALUES CAST('1998-11-22-03.44.55.123456' AS TIMESTAMP))
SELECT
ts1
,
HEX(ts1)
,
DEC(HEX(ts1),20)
,FLOAT(DEC(HEX(ts1),20))
,REAL (DEC(HEX(ts1),20))
FROM
tab1;
Figure 953, Convert Timestamp to number
=>
=>
=>
=>
=>
1998-11-22-03.44.55.123456
19981122034455123456
19981122034455123456.
1.99811220344551e+019
1.998112e+019
SELECT
empno
,firstnme
,lastname
,job
FROM
employee
WHERE
empno < '000100'
ORDER BY empno;
Figure 954, Sample query with no column control
SELECT
empno
,CASE :host-var-1
WHEN 1 THEN firstnme
ELSE
''
END
AS firstnme
,CASE :host-var-2
WHEN 1 THEN lastname
ELSE
''
END
AS lastname
,CASE :host-var-3
WHEN 1 THEN VARCHAR(job)
ELSE
''
END
AS job
FROM
employee
WHERE
empno < '000100'
ORDER BY empno;
Figure 955, Sample query with column control
SELECT
id
,salary
,INT(salary / 1500)
AS len
ANSWER
===================================
ID
SALARY
SALARY_CHART
--- -------- -------------------130 10505.90 *********
140 21150.00 ******************
150 19456.50 ****************
160 22959.20 ********************
170 12258.50 **********
180 12009.75 **********
WITH
temp1 (id, salary) AS
(SELECT
id
,salary
FROM
staff
WHERE
id > 120
AND
id < 190),
temp2 (max_sal) AS
(SELECT
INT(MAX(salary)) / 20
FROM
temp1)
SELECT
id
,salary
,VARCHAR(REPEAT('*',INT(salary / max_sal)),20) AS salary_chart
FROM
temp1
,temp2
ORDER BY id;
Figure 957, Make chart of fixed length
SELECT
sex
,COUNT(*) AS num
FROM
stats
GROUP BY sex
ORDER BY sex;
Figure 958, Use GROUP BY to get counts
ANSWER >>
SEX
--F
M
NUM
--595
405
SELECT
SELECT
COUNT(*) AS total
,SUM(CASE sex WHEN 'F' THEN 1 ELSE 0 END) AS female
,SUM(CASE sex WHEN 'M' THEN 1 ELSE 0 END) AS male
FROM
stats;
Figure 961, Use CASE and SUM to get counts
SELECT
years
,COUNT(*) AS #staff
FROM
staff
WHERE
UCASE(name) LIKE '%E%'
AND
years
<= 5
GROUP BY years;
Figure 962, Count staff joined per year
ANSWER
=============
YEARS #STAFF
----- -----1
1
4
2
5
3
ANSWER
============
YEARS #STAFF
----- -----0
0
1
1
2
0
3
0
4
2
5
3
ANSWER
============
YEARS #STAFF
----- -----0
0
1
1
2
0
3
0
4
2
5
3
ANSWER
======
YEAR#
----0
2
3
ELSE
1
END AS found
FROM
category cat
LEFT OUTER JOIN
employee emp
ON
cat.subcat
= 'ROWS IN TABLE'
OR
(cat.subcat
= 'NUMBER MALES'
AND
emp.sex
= 'M')
OR
(cat.subcat
= 'SALARY > $20K'
AND
emp.salary
> 20000)
OR
(cat.subcat
= 'NAME LIKE ABC%'
AND
emp.firstnme LIKE 'ABC%')
OR
(cat.dept
<> ''
AND
cat.dept
= emp.workdept)
)AS xxx
GROUP BY xxx.cat
,xxx.subcat
ORDER BY 1,2;
Figure 966, Multiple counts in one pass, SQL
CATEGORY SUBCATEGORY/DEPT
#ROWS
-------- ----------------------------- ----1ST
ROWS IN TABLE
32
2ND
SALARY > $20K
25
3RD
NAME LIKE ABC%
0
4TH
NUMBER MALES
19
5TH
ADMINISTRATION SYSTEMS
6
5TH
DEVELOPMENT CENTER
0
5TH
INFORMATION CENTER
3
5TH
MANUFACTURING SYSTEMS
9
5TH
OPERATIONS
5
5TH
PLANNING
1
5TH
SOFTWARE SUPPORT
4
5TH
SPIFFY COMPUTER SERVICE DIV.
3
5TH
SUPPORT SERVICES
1
Figure 967, Multiple counts in one pass, Answer
WITH
temp1 (id, data) AS
(VALUES (01,'SOME TEXT TO PARSE.')
,(02,'MORE SAMPLE TEXT.')
,(03,'ONE-WORD.')
,(04,'')
),
temp2 (id, word#, word, data_left) AS
(SELECT id
,SMALLINT(1)
,SUBSTR(data,1,
CASE LOCATE(' ',data)
WHEN 0 THEN LENGTH(data)
ELSE
LOCATE(' ',data)
END)
,LTRIM(SUBSTR(data,
)
SELECT
*
FROM
temp2
ORDER BY 1,2;
Figure 968, Break text into words - SQL
ID WORD# WORD
DATA_LEFT
-- ----- --------- -------------1
1 SOME
TEXT TO PARSE.
1
2 TEXT
TO PARSE.
1
3 TO
PARSE.
1
4 PARSE.
2
1 MORE
SAMPLE TEXT.
2
2 SAMPLE
TEXT.
2
3 TEXT.
3
1 ONE-WORD.
Figure 969, Break text into words - Answer
WHERE
AND
AND
)
SELECT
a.dept
a.name
a.name
(SELECT
FROM
WHERE
AND
= b.dept
> b.name
=
MIN(c.name)
staff c
c.dept = b.dept
c.name > b.name)
dept
,w#
,name AS max_name
,all_names
FROM
temp1 d
WHERE
w# =
(SELECT MAX(w#)
FROM
temp1 e
WHERE d.dept = e.dept)
ORDER BY dept;
Figure 970, Denormalize Normalized Data - SQL
FROM
dept
,SMALLINT(cnt)
,mxx
,list_names(dept)
(SELECT
dept
AS
AS
AS
AS
DEPT
W#
MAX_NAME
ALL_NAMES
IMPORTANT
============
This example
uses an "!"
as the stmt
delimiter.
,COUNT(*) as cnt
,MAX(name) AS mxx
FROM
staff
GROUP BY dept
)as ddd
ORDER BY dept!
Figure 972, Creating a function to denormalize names
WITH
data_input AS
(SELECT
dept
,job
,SUM(salary) AS sum_sal
FROM
staff
WHERE
id
< 200
AND
name
<> 'Sue'
AND
salary
> 10000
GROUP BY dept
,job),
jobs_list AS
(SELECT
job
,ROW_NUMBER() OVER(ORDER BY job ASC) AS job#A
,ROW_NUMBER() OVER(ORDER BY job DESC) AS job#D
FROM
data_input
GROUP BY job),
dept_list AS
(SELECT
dept
FROM
data_input
GROUP BY dept),
dept_jobs_list AS
(SELECT
dpt.dept
,job.job
,job.job#A
,job.job#D
FROM
jobs_list job
FULL OUTER JOIN
dept_list dpt
ON
1 = 1),
data_all_jobs AS
(SELECT
djb.dept
,djb.job
,djb.job#A
,djb.job#D
,COALESCE(dat.sum_sal,0) AS sum_sal
FROM
dept_jobs_list djb
LEFT OUTER JOIN
data_input
dat
ON
djb.dept = dat.dept
AND
djb.job = dat.job),
data_transform (dept, job#A, job#D, outvalue) AS
(SELECT
dept
,job#A
,job#D
,VARCHAR(num_to_char(sum_sal),250)
FROM
data_all_jobs
WHERE
job#A = 1
UNION ALL
SELECT
dat.dept
,dat.job#A
,dat.job#D
,trn.outvalue || ',' || num_to_char(dat.sum_sal)
FROM
data_transform trn
,data_all_jobs dat
WHERE
trn.dept = dat.dept
AND
trn.job#A = dat.job#A - 1),
data_last_row AS
(SELECT
dept
,num_to_char(dept) AS dept_char
,outvalue
FROM
data_transform
WHERE
job#D = 1),
Figure 974, Transform numeric data - part 1 of 2
FROM
jobs_last_row
UNION ALL
SELECT
dept
,dept_char
,outvalue
FROM
data_last_row)
SELECT
dept_char || ',' ||
outvalue AS output
FROM
data_and_jobs
ORDER BY dept;
Figure 975, Transform numeric data - part 2 of 2
DATA_INPUT
OUTPUT
===================
=====================================
DEPT JOB
SUM_SAL
DEPT,
Clerk,
Mgr,
Sales
---- ----- -------10,
0.00, 22959.20,
0.00
10 Mgr
22959.20
15, 24766.70, 20659.80, 16502.83
15 Clerk 24766.70
20, 27757.35, 18357.50, 18171.25
15 Mgr
20659.80
38, 24964.50, 17506.75, 34814.30
15 Sales 16502.83
42, 10505.90, 18352.80, 18001.75
20 Clerk 27757.35
51,
0.00, 21150.00, 19456.50
20 Mgr
18357.50
20 Sales 18171.25
38 Clerk 24964.50
38 Mgr
17506.75
38 Sales 34814.30
42 Clerk 10505.90
42 Mgr
18352.80
42 Sales 18001.75
51 Mgr
21150.00
51 Sales 19456.50
Figure 976, Contents of first temporary table and final output
--#SET DELIMITER !
IMPORTANT
============
This example
uses an "!"
as the stmt
delimiter.
ORDER BY id!
Figure 977, Reversing character field
30 Marenghi ihgneraM
SELECT
id
AS ID
,salary
AS SALARY1
,DEC(reverse(CHAR(salary)),7,4) AS SALARY2
FROM
staff
ANSWER
WHERE
id < 40
===================
ORDER BY id;
ID SALARY1 SALARY2
-- -------- ------10 18357.50 5.7538
20 18171.25 52.1718
30 17506.75 57.6057
Figure 978, Reversing numeric field
--#SET DELIMITER !
CREATE FUNCTION strp(in_val VARCHAR(20),in_strip VARCHAR(1))
RETURNS VARCHAR(20)
BEGIN ATOMIC
DECLARE cur_pos SMALLINT;
DECLARE stp_flg CHAR(1);
DECLARE out_val VARCHAR(20);
IF in_strip = '' THEN
SIGNAL SQLSTATE '75001'
SET MESSAGE_TEXT = 'Strip char is zero length';
END IF;
SET cur_pos = 1;
SET stp_flg = 'Y';
WHILE stp_flg = 'Y' AND cur_pos <= length(in_val) DO
IF SUBSTR(in_val,cur_pos,1) <> in_strip THEN
SET stp_flg = 'N';
ELSE
SET cur_pos = cur_pos + 1;
END IF;
END WHILE;
SET out_val = SUBSTR(in_val,cur_pos);
SET cur_pos = length(out_val);
SET stp_flg = 'Y';
IMPORTANT
============
This example
uses an "!"
as the stmt
delimiter.
ANSWER
========================
W# WORD_VAL
STP
LEN
-- ---------- ------ --1 00 abc 000 abc
5
2 0 0 abc
0 abc
6
3 sdbs
sdbs
5
4 000 0
1
5 0000
0
6 0
0
7 a
a
1
8
0
SELECT
id
,SUBSTR(CHAR(TIMESTAMP(GENERATE_UNIQUE())),18) AS ss_mmmmmm
,pause(id / 10)
AS #loops
,SUBSTR(CHAR(TIMESTAMP(GENERATE_UNIQUE())),18) AS ss_mmmmmm
FROM
staff
WHERE
id < 31;
ANSWER
=============================
ID SS_MMMMMM #LOOPS SS_MMMMMM
-- --------- ------ --------10 50.068593 76386 50.068587
20 52.068744 144089 52.068737
30 55.068930 206101 55.068923
Figure 984, Query that uses pause function
--#SET DELIMITER !
CREATE FUNCTION sort_char(in_val VARCHAR(20),sort_dir VARCHAR(1))
RETURNS VARCHAR(20)
BEGIN ATOMIC
DECLARE cur_pos SMALLINT;
DECLARE do_sort CHAR(1);
DECLARE out_val VARCHAR(20);
IF UCASE(sort_dir) NOT IN ('A','D') THEN
SIGNAL SQLSTATE '75001'
SET MESSAGE_TEXT = 'Sort order not ''A'' or ''D''';
END IF;
SET out_val = in_val;
SET do_sort = 'Y';
WHILE do_sort = 'Y' DO
ANSWER
=============================
W# WORD_VAL SA
SD
-- --------- ------- -------1 12345678 12345678 87654321
2 ABCDEFG ABCDEFG GFEDCBA
3 AaBbCc
aAbBcC
CcBbAa
4 abccb
abbcc
ccbba
5 '%#.
.'#%
%#'.
6 bB
bB
Bb
7 a
a
a
8
WITH numbered_rows AS
(SELECT
s.*
,ROW_NUMBER() OVER(PARTITION BY job
ORDER
BY salary, id) AS row#
FROM
staff s
WHERE
comm
> 0
AND
name LIKE '%e%'),
median_row_num AS
(SELECT
job
,(MAX(row# + 1.0) / 2) - 0.5 AS med_lo
,(MAX(row# + 1.0) / 2) + 0.5 AS med_hi
FROM
numbered_rows
GROUP BY job)
SELECT
nn.job
,DEC(AVG(nn.salary),7,2) AS med_sal
FROM
numbered_rows
nn
,median_row_num mr
WHERE
nn.job
= mr.job
AND
nn.row# BETWEEN mr.med_lo AND mr.med_hi
GROUP BY nn.job
ORDER BY nn.job;
Figure 987, Calculating the median
ANSWER
==============
JOB
MED_SAL
----- -------Clerk 13030.50
Sales 17432.10
WITH numbered_rows AS
(SELECT
s.*
,ROW_NUMBER() OVER(PARTITION BY job
ORDER
BY salary, id) AS row#
FROM
staff s
WHERE
comm
> 0
AND
name LIKE '%e%'),
median_row_num AS
(SELECT
job
,(MAX(row# + 1.0) / 2) - 0.5 AS med_lo
,(MAX(row# + 1.0) / 2) + 0.5 AS med_hi
,DEC(AVG(salary),7,2)
AS avg_sal
,COUNT(*)
AS #rows
FROM
numbered_rows
GROUP BY job)
SELECT
nn.job
,DEC(AVG(nn.salary),7,2) AS med_sal
,MAX(mr.avg_sal)
AS avg_sal
,MAX(mr.#rows)
AS #r
FROM
numbered_rows
nn
,median_row_num mr
ANSWER
WHERE
nn.job
= mr.job
==========================
AND
nn.row# BETWEEN mr.med_lo
JOB
MED_SAL AVG_SAL #R
AND mr.med_hi
----- -------- -------- -GROUP BY nn.job
Clerk 13030.50 12857.56 7
ORDER BY nn.job;
Sales 17432.10 17460.93 4
Figure 988, Get median plus average
WITH numbered_rows AS
(SELECT
s.*
,ROW_NUMBER() OVER(PARTITION BY job
ORDER
BY salary, id) AS row#
FROM
staff s
WHERE
comm
> 0
AND
name LIKE '%e%'),
median_row_num AS
(SELECT
job
,MAX(row# + 1) / 2 AS med_row#
FROM
numbered_rows
GROUP BY job)
SELECT
nn.job
,nn.salary AS med_sal
FROM
numbered_rows
nn
,median_row_num mr
WHERE
nn.job = mr.job
AND
nn.row# = mr.med_row#
ORDER BY nn.job;
Figure 989, Calculating the median
ANSWER
==============
JOB
MED_SAL
----- -------Clerk 13030.50
Sales 16858.20
WITH numbered_rows AS
(SELECT
s.*
,ROW_NUMBER() OVER(PARTITION BY job
ORDER
BY salary, id) AS row#
FROM
staff s
WHERE
comm
> 0
AND
name LIKE '%e%')
SELECT
job
,salary AS med_sal
FROM
numbered_rows
WHERE
(job,row#) IN
ANSWER
(SELECT
job
==============
,MAX(row# + 1) / 2
JOB
MED_SAL
FROM
numbered_rows
----- -------GROUP BY job)
Clerk 13030.50
ORDER BY job;
Sales 16858.20
Figure 990, Calculating the median
WITH numbered_rows AS
(SELECT
s.*
,ROW_NUMBER() OVER(PARTITION BY job
ORDER
BY salary, id) AS row#
FROM
staff s
WHERE
comm
> 0
AND
name LIKE '%e%')
SELECT
r1.*
,(SELECT r2.salary
FROM
numbered_rows r2
WHERE
r2.job = r1.job
AND
r2.row# = (SELECT MAX(r3.row# + 1) / 2
FROM
numbered_rows r3
WHERE
r2.job = r3.job)) AS med_sal
FROM
numbered_rows r1
ORDER BY job
,salary;
Figure 991, List matching rows and median
SELECT
*
FROM
supermarket_sales
WHERE
DATE(sales_ts) = '2003-08-01'
ORDER BY sales_ts;
Figure 996, Select rows for given date
SELECT
ANSWER
=========
ANSWER
======
C1
-A
FROM
WHERE
supermarket_sales
sales_ts BETWEEN '2003-08-01-00.00.00'
AND '2003-08-01-24.00.00'
ORDER BY sales_ts;
Figure 997, Select rows for given date
SELECT
creator
FROM
sysibm.systables
WHERE
creator = 'ZZZ';
Figure 998, Query with no matching rows (1 of 8)
ANSWER
========
SELECT
MAX(creator)
FROM
sysibm.systables
WHERE
creator = 'ZZZ';
Figure 999, Query with no matching rows (2 of 8)
ANSWER
======
SELECT
MAX(creator)
FROM
sysibm.systables
WHERE
creator = 'ZZZ'
HAVING
MAX(creator) IS NOT NULL;
Figure 1000, Query with no matching rows (3 of 8)
ANSWER
========
SELECT
MAX(creator)
FROM
sysibm.systables
WHERE
creator
= 'ZZZ'
HAVING
MAX(creator) = 'ZZZ';
Figure 1001, Query with no matching rows (4 of 8)
ANSWER
========
SELECT
MAX(creator)
FROM
sysibm.systables
WHERE
creator = 'ZZZ'
GROUP BY creator;
Figure 1002, Query with no matching rows (5 of 8)
ANSWER
========
SELECT
creator
FROM
sysibm.systables
WHERE
creator = 'ZZZ'
GROUP BY creator;
Figure 1003, Query with no matching rows (6 of 8)
ANSWER
========
SELECT
COUNT(*)
FROM
sysibm.systables
WHERE
creator = 'ZZZ'
GROUP BY creator;
Figure 1004, Query with no matching rows (7 of 8)
ANSWER
========
SELECT
COUNT(*)
FROM
sysibm.systables
WHERE
creator = 'ZZZ';
Figure 1005, Query with no matching rows (8 of 8)
ANSWER
======
0
SELECT
COALESCE(name,noname) AS nme
,COALESCE(salary,nosal) AS sal
FROM
(SELECT
'NO NAME' AS noname
,0
AS nosal
FROM
sysibm.sysdummy1
)AS nnn
LEFT OUTER JOIN
(SELECT
*
FROM
staff
WHERE
id < 5
)AS xxx
ON
1 = 1
ORDER BY name;
Figure 1006, Always get a row, example 1 of 2
ANSWER
============
NME
SAL
------- ---NO NAME 0.00
ANSWER
============
NME
SAL
------- ---NO NAME 0.00
ON
1 = 1
ORDER BY NAME;
Figure 1007, Always get a row, example 2 of 2
SELECT
FROM
DATE('2001-09-22')
sysibm.sysdummy1;
ANSWER
==========
2001-09-22
SELECT
FROM
DATE(2001-09-22)
sysibm.sysdummy1;
ANSWER
==========
0006-05-24
SELECT
id
,name
FROM
staff
WHERE
id <= 100
AND
id
= (INT(RAND()* 10) * 10) + 10
ORDER BY id;
Figure 1010, Get random rows - Incorrect
WITH temp AS
(SELECT
id
,name
,(INT(RAND(0)* 10) * 10) + 10 AS ran
FROM
staff
WHERE
id <= 100
)
SELECT
t.*
,CASE id
WHEN ran THEN 'Y'
ELSE
' '
END AS eql
FROM
temp t
ORDER BY id;
Figure 1011, Get random rows - Explanation
ANSWER
===========
ID NAME
-- -------30 Marenghi
60 Quigley
ANSWER
====================
ID NAME
RAN EQL
--- -------- --- --10 Sanders
10 Y
20 Pernal
30
30 Marenghi 70
40 O'Brien
10
50 Hanes
30
60 Quigley
40
70 Rothman
30
80 James
100
90 Koonitz
40
100 Plotz
100 Y
WITH
staff_numbered AS
(SELECT s.*
,ROW_NUMBER() OVER() AS row#
FROM
staff s
WHERE
id <= 100
),
count_rows AS
(SELECT MAX(row#) AS #rows
FROM
staff_numbered
),
random_values (RAN#) AS
(VALUES (RAND())
,(RAND())
,(RAND())
),
rows_t0_get AS
(SELECT INT(ran# * #rows) + 1 AS get_row
FROM
random_values
,count_rows
)
SELECT
id
,name
FROM
staff_numbered
,rows_t0_get
WHERE
row# = get_row
ORDER BY id;
Figure 1012, Get random rows - Non-distinct
ANSWER
===========
ID NAME
--- ------10 Sanders
20 Pernal
90 Koonitz
SELECT
ANSWER
===========
ID NAME
-- -------10 Sanders
40 O'Brien
60 Quigley
id
,name
FROM
(SELECT s.*
,ROW_NUMBER() OVER(ORDER BY RAND()) AS r
FROM
staff s
WHERE id <= 100
)AS xxx
WHERE
r <= 3
ORDER BY id;
Figure 1013, Get random rows - Distinct
ANSWER
======
BGN_TSTAMP
ELP_SEC
-------------------------- ------2001-01-15-01.02.03.000000
1.234
2001-01-15-01.02.03.123456
1.234
Figure 1014, Date/Time manipulation - wrong
END_TSTAMP
-------------------------2001-01-15-01.02.04.000000
2001-01-15-01.02.04.123456
ANSWER
======
BGN_TSTAMP
ELP_SEC
-------------------------- ------2001-01-15-01.02.03.000000
1.234
2001-01-15-01.02.03.123456
1.234
Figure 1015, Date/Time manipulation - right
END_TSTAMP
-------------------------2001-01-15-01.02.04.234000
2001-01-15-01.02.04.357456
ANSWER
======
C0
-A
B
ANSWER
======
C0
-A
ANSWER
======
C0
-A
B
SELECT
FROM
SUM(INTEGER(salary)) AS s1
,INTEGER(SUM(salary)) AS s2
staff;
ANSWER
=============
S1
S2
------ -----583633 583647
SELECT
FROM
SUM(INTEGER(ROUND(salary,-1))) AS s1
,INTEGER(SUM(salary)) AS s2
staff;
ANSWER
=============
S1
S2
------ -----583640 583647
SELECT
lastname
,sex
,CASE
WHEN sex >=
WHEN sex >=
END AS sxx
FROM
employee
WHERE
lastname LIKE
ORDER BY 1;
Figure 1022, Case WHEN
lastname
,sex
,CASE
WHEN sex >=
WHEN sex >=
END AS sxx
FROM
employee
WHERE
lastname LIKE
ORDER BY 1;
Figure 1023, Case WHEN
ANSWER
=================
LASTNAME
SX SXX
---------- -- --JEFFERSON M FEM
JOHNSON
F FEM
JONES
M FEM
SELECT
SELECT
AVG(salary) / AVG(comm) AS a1
,AVG(salary / comm)
AS a2
FROM
staff;
Figure 1024, Division and Average
SELECT
FROM
WHERE
ORDER BY
ANSWER
=================
LASTNAME
SX SXX
---------- -- --JEFFERSON M MAL
JOHNSON
F FEM
JONES
M MAL
ANSWER >>>
hiredate
employee
hiredate < '1960-01-01'
1;
SELECT
FROM
WHERE
ORDER BY
CHAR(hiredate,USA)
employee
hiredate < '1960-01-01'
1;
A1
-32
A2
----61.98
ANSWER
==========
1947-05-05
1949-08-17
1958-05-16
ANSWER
==========
05/05/1947
05/16/1958
08/17/1949
EXEC-SQL
DECLARE fred CURSOR FOR
SELECT
*
FROM
staff
WHERE
id < 1000
ORDER BY id;
END-EXEC;
EXEC-SQL
OPEN fred
END-EXEC;
DO UNTIL SQLCODE = 100;
EXEC-SQL
FETCH fred
INTO :HOST-VARS
END-EXEC;
IF SQLCODE <> 100 THEN DO;
SET HOST-VAR.ID = HOST-VAR.ID + 500;
EXEC-SQL
INSERT INTO staff VALUES (:HOST-VARS)
END-EXEC;
END-DO;
END-DO;
EXEC-SQL
CLOSE fred
END-EXEC;
Figure 1027, Ambiguous Cursor
SELECT
region_code
AS region
,product_type AS ptype
,order_number AS order#
,order_value
AS value
FROM
order_table
WHERE
order_date = '2005-12-22'
ORDER BY region_code
,product_type
WITH CS;
Figure 1028, Select from ORDER table
REGION
-----EAST
EAST
EAST
EAST
PTYPE
----GOOD
JUNK
NICE
NICE
ORDER#
-----111
222
333
444
VALUE
----4.66
6.33
123.45
123.45
EAST
TRASH
111
4.66
Figure 1029, Sample query output
<---+
SAME RESULT
CURSOR "WITH" OPTION
IF RUN TWICE
===================== ============
RR - Repeatable Read
Yes
RS - Read Stability
No (inserts)
CS - Cusor Stability
No (all DML)
UR - Uncommitted Read No (all DML)
Figure 1030, WITH Option vs. Actions
FETCH SAME
ROW > ONCE
==========
Never
Never
Maybe
Maybe
UNCOMMITTED
ROWS SEEN
===========
Never
Never
Never
Yes
ROWS
LOCKED
========
Many/All
Many/All
Current
None
FLOAT1
DECIMAL1
BIGINT1
------------------------ -------------------- ------------------+1.23456789000000E+000
1.
1
+1.23456789000000E+001
12.
12
+1.23456789000000E+002
123.
123
+1.23456789000000E+003
1234.
1234
+1.23456789000000E+004
12345.
12345
+1.23456789000000E+005
123456.
123456
+1.23456789000000E+006
1234567.
1234567
+1.23456789000000E+007
12345678.
12345678
+1.23456789000000E+008
123456789.
123456788
+1.23456789000000E+009
1234567890.
1234567889
+1.23456789000000E+010
12345678900.
12345678899
+1.23456789000000E+011
123456789000.
123456788999
+1.23456789000000E+012
1234567890000.
1234567889999
+1.23456789000000E+013
12345678900000.
12345678899999
+1.23456789000000E+014
123456789000000.
123456788999999
+1.23456789000000E+015
1234567890000000.
1234567889999999
+1.23456789000000E+016
12345678900000000.
12345678899999998
+1.23456789000000E+017
123456789000000000.
123456788999999984
+1.23456789000000E+018 1234567890000000000. 1234567889999999744
Figure 1032, Multiply floating-point number by ten, answer
WITH
temp1 (dec1, dbl1) AS
(VALUES (DECIMAL(1),DOUBLE(1)))
,temp2 (dec1, dec2, dbl1, dbl2) AS
(SELECT dec1
,dec1 / 3 AS dec2
,dbl1
ANSWER (1 row returned)
,dbl1 / 3 AS dbl2
==============================
FROM
temp1)
DEC1 = 1.0
SELECT *
DEC2 = 0.33333333333333333333
FROM
temp2
DBL1 = +1.00000000000000E+000
WHERE dbl2 <> dec2;
DBL2 = +3.33333333333333E-001
Figure 1035, Comparing float and decimal division
FROM
WHERE
,d1 * 10
temp
f1 < 1E9
)
SELECT f1
,d1
,CASE
WHEN d1 = f1 THEN 'SAME'
ELSE
'DIFF'
END AS compare
FROM
temp;
Figure 1036, Comparing float and decimal multiplication, SQL
F1
D1
COMPARE
---------------------- --------------------- ------+1.23456789000000E+000
1.2345678900 SAME
+1.23456789000000E+001
12.3456789000 SAME
+1.23456789000000E+002
123.4567890000 DIFF
+1.23456789000000E+003
1234.5678900000 DIFF
+1.23456789000000E+004
12345.6789000000 DIFF
+1.23456789000000E+005
123456.7890000000 DIFF
+1.23456789000000E+006
1234567.8900000000 SAME
+1.23456789000000E+007
12345678.9000000000 DIFF
+1.23456789000000E+008
123456789.0000000000 DIFF
+1.23456789000000E+009 1234567890.0000000000 DIFF
Figure 1037, Comparing float and decimal multiplication, answer