SQL Example
SQL Example
SQL Example
id ANSWER
+----------+ +--------+ ,nm.name ================
|ID|NAME | |ID|JOB | ,jb.job ID NAME JOB
|--|-------| |--|-----| FROM emp_nm nm -- ------- -----
|10|Sanders| |10|Sales| ,emp_jb jb 10 Sanders Sales
|20|Pernal | |20|Clerk| WHERE nm.id = jb.id 20 Pernal Clerk
|50|Hanes | +--------+ ORDER BY 1;
+----------+
Figure 1, Join example
indianZombie | www.indianzombie.blogspot.com 1
EMP_JB SELECT id
+--------+ ,job ANSWER
|ID|JOB | ,ROW_NUMBER() OVER(ORDER BY job) AS R ==========
|--|-----| FROM emp_jb ID JOB R
|10|Sales| ORDER BY job; -- ----- -
|20|Clerk| 20 Clerk 1
+--------+ 10 Sales 2
Figure 5, Assign row-numbers example
indianZombie | www.indianzombie.blogspot.com 2
INPUT DATA Recursive SQL ANSWER
=========== ============> =================
TEXT LINE# "Some silly text"
----- -----
Some 1
silly 2
text 3
Figure 9, Convert rows to string
indianZombie | www.indianzombie.blogspot.com 3
SELECT job ANSWER
,dept ==========================
,SUM(salary) AS sum_sal JOB DEPT SUM_SAL #EMPS
,COUNT(*) AS #emps ----- ---- --------- -----
FROM staff Clerk 15 84766.70 2
WHERE dept < 30 Clerk 20 77757.35 2
AND salary < 90000 Clerk - 162524.05 4
AND job < 'S' Mgr 10 243453.45 3
GROUP BY ROLLUP(job, dept) Mgr 15 80659.80 1
ORDER BY job Mgr - 324113.25 4
,dept; - - 486637.30 8
Figure 13, Subtotal and Grand-total example
--#SET DELIMITER !
SELECT name FROM staff WHERE id = 10!
--#SET DELIMITER ;
SELECT name FROM staff WHERE id = 20;
Figure 16, Set Delimiter example
indianZombie | www.indianzombie.blogspot.com 4
,bonus DECIMAL (00009,02)
,comm DECIMAL (00009,02)
)
DATA CAPTURE NONE;
Figure 17, DB2 sample table - EMPLOYEE
indianZombie | www.indianzombie.blogspot.com 5
CREATE ALIAS employee_al1 FOR employee;
COMMIT;
SELECT *
FROM staff TABLESAMPLE BERNOULLI(10);
Figure 24, TABLESAMPLE example
indianZombie | www.indianzombie.blogspot.com 6
CREATE TABLE default_values
(c1 CHAR NOT NULL
,d1 DECIMAL NOT NULL);
Figure 26, Table with default column lengths
-NaN -sNan -infinity -1.2 -1.20 0 1.20 1.2 infinity sNaN NaN
Figure 30, DECFLOAT value order
indianZombie | www.indianzombie.blogspot.com 7
ANSWER
WITH temp1 (d1, d2) AS ======
(VALUES (DECFLOAT(+1.0), DECFLOAT(+1.00)) 1
,(DECFLOAT(-1.0), DECFLOAT(-1.00)) -1
,(DECFLOAT(+0.0), DECFLOAT(+0.00)) 1
,(DECFLOAT(-0.0), DECFLOAT(-0.00)) 1
,(DECFLOAT(+0), DECFLOAT(-0)) 0
)
SELECT TOTALORDER(d1,d2)
FROM temp1;
Figure 31, Equal values that may have different orders
indianZombie | www.indianzombie.blogspot.com 8
Figure 33, Labeled Durations and Date/Time Types
ANSWER
==========
SELECT sales_date <= 1995-12-31
,sales_date- 10 DAY AS d1 <= 1995-12-21
,sales_date+ -1 MONTH AS d2 <= 1995-11-30
,sales_date+ 99 YEARS AS d3 <= 2094-12-31
,sales_date+ 55 DAYS
- 22 MONTHS AS d4 <= 1994-04-24
,sales_date + (4+6) DAYS AS d5 <= 1996-01-10
FROM sales
WHERE sales_person = 'GOUNOT'
AND sales_date = '1995-12-31'
Figure 34, Example, Labeled Duration usage
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 35, Adding Months - Varying Results
indianZombie | www.indianzombie.blogspot.com 9
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 37, 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 38, Subtracting a Date Duration
indianZombie | www.indianzombie.blogspot.com 10
Figure 39, DB2 Special Registers
SELECT id
,usa_sales + eur_sales AS tot_sales
FROM customer;
Figure 44, Silly query, but works
indianZombie | www.indianzombie.blogspot.com 11
CREATE DISTINCT TYPE USA_DOLLARS AS DECIMAL(9,2) WITH COMPARISONS;
CREATE DISTINCT TYPE EUR_DOLLARS AS DECIMAL(9,2) WITH COMPARISONS;
Figure 45, Create Distinct Type examples
SELECT id
,usa_sales + eur_sales AS tot_sales
FROM customer;
Figure 47, Silly query, now fails
SELECT id
,DECIMAL(usa_sales) +
DECIMAL(eur_sales) AS tot_sales
FROM customer;
Figure 48, Silly query, works again
WITH
get_matching_rows AS
(
SELECT id
,name
,salary SUBSELECT
FROM staff
WHERE id < 50
UNION ALL FULLSELECT
SELECT id
,name
indianZombie | www.indianzombie.blogspot.com 12
,salary SUBSELECT
FROM staff
WHERE id = 100
)
SELECT *
FROM get_matching_rows COMMON TABLE
ORDER BY id EXPRESSION
FETCH FIRST 10 ROWS ONLY SUBSELECT
FOR FETCH ONLY
WITH UR;
Figure 49, Query components
indianZombie | www.indianzombie.blogspot.com 13
ORDER BY 1; B01 B01 PLANNING
D11 D11 MANUFACTU
Figure 54, Select an individual column, and all columns
indianZombie | www.indianzombie.blogspot.com 14
,id DESC 10 Quill 290
FETCH FIRST 3 ROWS ONLY;
Figure 59, FETCH FIRST with ORDER BY, gets right answer
indianZombie | www.indianzombie.blogspot.com 15
WHERE "..." = '3978'; 000010 I 3978
Figure 63, View field names defined using AS
SELECT 'JOHN' AS J1
,'JOHN''S' AS J2 ANSWER
,'''JOHN''S''' AS J3 =============================
,'"JOHN''S"' AS J4 J1 J2 J3 J4
FROM staff ---- ------ -------- --------
WHERE id = 10; JOHN JOHN'S 'JOHN'S' "JOHN'S"
Figure 67, Quote usage
indianZombie | www.indianzombie.blogspot.com 16
FROM staff s 20 20 8 ABC "
WHERE id < 40 30 38 5 ABC "
ORDER BY "USER ID";
Figure 68, Double-quote usage
indianZombie | www.indianzombie.blogspot.com 17
Figure 74, Quantified Predicate syntax
indianZombie | www.indianzombie.blogspot.com 18
SELECT id, job ANSWER
FROM staff a =========
WHERE EXISTS ID JOB
(SELECT * --- -----
FROM staff b 10 Mgr
WHERE b.id = a.id 20 Sales
AND b.id < 50) 30 Mgr
ORDER BY id; 40 Sales
Figure 80, EXISTS Predicate example
indianZombie | www.indianzombie.blogspot.com 19
OR name LIKE '%r_%a' 130 Yamaguchi
ORDER BY id; 200 Scoutten
Figure 85, LIKE Predicate examples
SELECT id ANSWER
FROM staff ======
WHERE id = 10 ID
AND 'ABC' LIKE 'AB%' ---
AND 'A%C' LIKE 'A/%C' ESCAPE '/' 10
AND 'A_C' LIKE 'A\_C' ESCAPE '\'
AND 'A_$' LIKE 'A$_$$' ESCAPE '$';
Figure 87, LIKE and ESCAPE examples
indianZombie | www.indianzombie.blogspot.com 20
SELECT id
,name
FROM staff
WHERE name LIKE '%a' || X'3B' || '%'
ORDER BY id;
Figure 90, Refer to semi-colon in SQL text
indianZombie | www.indianzombie.blogspot.com 21
WHERE col1 = 'C' A AA |COL1|COL2|
AND col1 >= 'A' B BB |----|----|
OR col2 >= 'AA' C CC |A |AA |
ORDER BY col1; |B |BB |
|C |CC |
SELECT * ANSWER>> COL1 COL2 +---------+
FROM table1 ---- ----
WHERE (col1 = 'C' A AA
AND col1 >= 'A') B BB
OR col2 >= 'AA' C CC
ORDER BY col1;
FROM clause
JOIN ON clause
WHERE clause
GROUP BY and aggregate
HAVING clause
SELECT list
ORDER BY clause
FETCH FIRST
Figure 95, Query Processing Sequence
SELECT id ANSWER
,salary =================
,CAST(salary AS INTEGER) AS sal2 ID SALARY SAL2
FROM staff -- -------- -----
WHERE id < 30 10 98357.50 98357
ORDER BY id; 20 78171.25 78171
Figure 97, Use CAST expression to convert Decimal to Integer
SELECT id ANSWER
indianZombie | www.indianzombie.blogspot.com 22
,job =============
,CAST(job AS CHAR(3)) AS job2 ID JOB JOB2
FROM staff -- ----- ----
WHERE id < 30 10 Mgr Mgr
ORDER BY id; 20 Sales Sal
Figure 98, Use CAST expression to truncate Char field
SELECT id ANSWER
,CAST(NULL AS SMALLINT) AS junk =======
FROM staff ID JUNK
WHERE id < 30 -- ----
ORDER BY id; 10 -
20 -
Figure 99, Use CAST expression to define SMALLINT field with null values
indianZombie | www.indianzombie.blogspot.com 23
VALUES 6 <= 1 row, 1 column
VALUES (6) <= 1 row, 1 column
VALUES 6, 7, 8 <= 1 row, 3 columns
VALUES (6), (7), (8) <= 3 rows, 1 column
VALUES (6,66), (7,77), (8,NULL) <= 3 rows, 2 columns
Figure 103, VALUES usage examples
indianZombie | www.indianzombie.blogspot.com 24
SELECT * 1.0 BB
FROM temp1; 2.0 -
Figure 107, Use VALUES to define a temporary table (2 of 4)
indianZombie | www.indianzombie.blogspot.com 25
Figure 111, Define a view using a VALUES clause
SELECT * ANSWER
FROM (VALUES (123,'ABC') ======
,(234,'DEF') --- ---
)AS ttt 234 DEF
ORDER BY 1 DESC; 123 ABC
Figure 113, Generate table with unnamed columns
SELECT id ANSWER
,salary AS sal ===============================
,comm AS com ID SAL COM COMBO TYP
,combo -- -------- ------ -------- ---
,typ 10 98357.50 - - COM
FROM staff 10 98357.50 - 98357.50 SAL
,TABLE(VALUES(salary,'SAL') 20 78171.25 612.45 612.45 COM
,(comm, 'COM') 20 78171.25 612.45 78171.25 SAL
)AS tab(combo,typ) 30 77506.75 - - COM
WHERE id < 40 30 77506.75 - 77506.75 SAL
ORDER BY id
,typ;
Figure 114, Combine columns example
indianZombie | www.indianzombie.blogspot.com 26
,sex AS sx ====================
,CASE sex LASTNAME SX SEXX
WHEN 'F' THEN 'FEMALE' ---------- -- ------
WHEN 'M' THEN 'MALE' JEFFERSON M MALE
ELSE NULL JOHN F FEMALE
END AS sexx JOHNSON F FEMALE
FROM employee JONES M MALE
WHERE lastname LIKE 'J%'
ORDER BY 1;
Figure 116, Use CASE (1st type) to expand a value
indianZombie | www.indianzombie.blogspot.com 27
FROM employee --- -- --
WHERE lastname LIKE 'J%'; 4 2 2
Figure 120, Use CASE to get multiple counts in one pass
UPDATE staff
SET comm = CASE dept
WHEN 15 THEN comm * 1.1
WHEN 20 THEN comm * 1.2
WHEN 38 THEN
CASE
WHEN years < 5 THEN comm * 1.3
WHEN years >= 5 THEN comm * 1.4
ELSE NULL
END
ELSE comm
END
WHERE comm IS NOT NULL
AND dept < 50;
Figure 122, UPDATE statement with nested CASE expressions
indianZombie | www.indianzombie.blogspot.com 28
SELECT lastname ANSWER
,sex =================
,CASE LASTNAME SX SXX
WHEN sex >= 'M' THEN 'MAL' ---------- -- ---
WHEN sex >= 'F' THEN 'FEM' JEFFERSON M MAL
END AS sxx JOHN F FEM
FROM employee JOHNSON F FEM
WHERE lastname LIKE 'J%' JONES M MAL
ORDER BY 1;
Figure 124, Use CASE to derive a value (correct)
SELECT id ANSWER
,dept =======================
,salary ID DEPT SALARY COMM
,comm --- ---- -------- -----
FROM staff 130 42 10505.90 75.60
WHERE CASE 270 66 18555.50 -
WHEN comm < 70 THEN 'A' 330 66 10988.00 55.50
WHEN name LIKE 'W%' THEN 'B'
WHEN salary < 11000 THEN 'C'
WHEN salary < 18500
AND dept <> 33 THEN 'D'
WHEN salary < 19000 THEN 'E'
END IN ('A','C','E')
ORDER BY id;
Figure 126, Use CASE in a predicate
ANSWER
=======================
ID DEPT SALARY COMM
SELECT id --- ---- -------- -----
indianZombie | www.indianzombie.blogspot.com 29
,name 130 42 10505.90 75.60
,salary 270 66 18555.50 -
,comm 330 66 10988.00 55.50
FROM staff
WHERE (comm < 70)
OR (salary < 11000 AND NOT name LIKE 'W%')
OR (salary < 19000 AND NOT (name LIKE 'W%'
OR (salary < 18500 AND dept <> 33)))
ORDER BY id;
Figure 127, Same stmt as prior, without CASE predicate
indianZombie | www.indianzombie.blogspot.com 30
END-DO
CLOSE fred
Figure 130, Use cursor in program
SELECT name
,salary
INTO :name-var
,:salary-var
FROM staff
WHERE id = :id-var
Figure 131, Singleton select
SQLDA Information
sqldaid : SQLDA sqldabc: 896 sqln: 20 sqld: 7
Column Information
indianZombie | www.indianzombie.blogspot.com 31
485 DECIMAL 7, 2 COMM 4
Figure 135, DESCRIBE the output columns in a select statement
SET (:hv1
,:hv2
,:hv3) =
(SELECT id
,name
,salary
FROM staff
WHERE id = :id-var)
Figure 139, SET using row-fullselect
SET CONNECTION
SET CURRENT DEFAULT TRANSFORM GROUP
indianZombie | www.indianzombie.blogspot.com 32
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 140, Other SET statements
indianZombie | www.indianzombie.blogspot.com 33
Figure 146, INSERT statement syntax
INSERT INTO
(SELECT *
FROM emp_act_copy
WHERE empno < '1'
)
VALUES ('510000' ,'ABC' ,10 ,1.4 ,'2003-10-22', '2003-11-24');
Figure 151, Insert into a fullselect
indianZombie | www.indianzombie.blogspot.com 34
SELECT LTRIM(CHAR(id + 600000))
,SUBSTR(UCASE(name),1,6)
,salary / 229
,123
,CURRENT DATE
,'2003-11-11'
FROM staff
WHERE id < 50;
Figure 152,Insert result of select statement
indianZombie | www.indianzombie.blogspot.com 35
,CHAR(col1)
,col1 / 2
FROM temp1;
Figure 156, Insert from common table expression
INSERT INTO
(SELECT *
FROM us_customer
UNION ALL
SELECT *
FROM intl_customer)
VALUES (111,'Fred','USA')
,(222,'Dave','USA')
,(333,'Juan','MEX');
Figure 159, Insert into multiple tables
UPDATE emp_act_copy
SET emptime = NULL
,emendate = DEFAULT
,emstdate = CURRENT DATE + 2 DAYS
,actno = ACTNO / 2
indianZombie | www.indianzombie.blogspot.com 36
,projno = 'ABC'
WHERE empno = '100000';
Figure 160, Single row update
UPDATE emp_act_copy
SET actno = actno / 2;
Figure 162, Mass update
UPDATE emp_act_copy
SET actno = (SELECT MAX(salary) / 10
FROM staff)
WHERE empno = '200000';
Figure 164, Update using select
UPDATE emp_act_copy
SET (actno
,emstdate
,projno) = (SELECT MAX(salary) / 10
,CURRENT DATE + 2 DAYS
,MIN(CHAR(id))
FROM staff
WHERE id <> 33)
WHERE empno LIKE '600%';
Figure 165, Multi-row update using select
indianZombie | www.indianzombie.blogspot.com 37
UPDATE emp_act_copy ac1
SET (actno
,emptime) = (SELECT ac2.actno + 1
,ac1.emptime / 2
FROM emp_act_copy ac2
WHERE ac2.empno LIKE '60%'
AND SUBSTR(ac2.empno,3) = SUBSTR(ac1.empno,3))
WHERE EMPNO LIKE '700%';
Figure 166, Multi-row update using correlated select
UPDATE emp_act_copy
SET emptime = 10
WHERE empno = '000010'
AND projno = 'MA2100';
Figure 167, Direct update of table
UPDATE
(SELECT *
FROM emp_act_copy
WHERE empno = '000010'
AND projno = 'MA2100'
)AS ea
SET emptime = 20;
Figure 168, Update of fullselect
UPDATE
(SELECT *
FROM staff
ORDER BY salary DESC
FETCH FIRST 5 ROWS ONLY
)AS xxx
SET comm = 10000;
Figure 169, Update first "n" rows
indianZombie | www.indianzombie.blogspot.com 38
UPDATE
(SELECT ea1.*
,MAX(emptime) OVER(PARTITION BY empno) AS maxtime
FROM emp_act_copy ea1
)AS ea2
SET emptime = maxtime
WHERE empno = '000010'
AND projno = 'MA2100';
Figure 171, Use OLAP function to get max-time, then apply (correct)
UPDATE emp_act_copy
SET emptime = MAX(emptime) OVER(PARTITION BY empno)
WHERE empno = '000010'
AND projno = 'MA2100';
Figure 172, Use OLAP function to get max-time, then apply (wrong)
indianZombie | www.indianzombie.blogspot.com 39
DELETE
FROM emp_act_copy
WHERE empno = '000010'
AND projno = 'MA2100'
AND actno = 10;
Figure 175, Single-row delete
DELETE
FROM emp_act_copy;
Figure 177, Mass delete
DELETE
FROM emp_act_copy
WHERE empno LIKE '00%'
AND projno >= 'MA';
Figure 178, Selective delete
DELETE
FROM staff s1
WHERE id NOT IN
(SELECT MAX(id)
FROM staff s2
WHERE s1.dept = s2.dept);
Figure 179, Correlated delete (1 of 2)
DELETE
FROM staff s1
WHERE EXISTS
(SELECT *
FROM staff s2
WHERE s2.dept = s1.dept
indianZombie | www.indianzombie.blogspot.com 40
AND s2.id > s1.id);
Figure 180, 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 181, Delete using fullselect and OLAP function
DELETE
FROM (SELECT *
FROM staff
ORDER BY salary DESC
FETCH FIRST 5 ROWS ONLY
)AS xxx;
Figure 182, Delete first "n" rows
ANSWER
==============
SELECT empno EMPNO PRJ ACT
,projno AS prj ------ --- ---
,actno AS act 200000 ABC 10
FROM FINAL TABLE 200000 DEF 10
(INSERT INTO emp_act_copy
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 184, Select rows inserted
indianZombie | www.indianzombie.blogspot.com 41
FROM FINAL TABLE 300000 ZZZ 999 1
(INSERT INTO emp_act_copy (empno, projno, actno) 300000 VVV 111 2
INCLUDE (row# SMALLINT)
VALUES ('300000','ZZZ',999,1)
,('300000','VVV',111,2))
ORDER BY row#;
Figure 185, Include column to get insert sequence
indianZombie | www.indianzombie.blogspot.com 42
SELECT projno AS prj ANSWER
,old_t AS old_t ===============
,emptime AS new_t PRJ OLD_T NEW_T
FROM NEW TABLE --- ----- -----
(UPDATE emp_act_copy ABC 2.00 0.02
INCLUDE (old_t DECIMAL(5,2)) DEF 2.00 11.27
SET emptime = emptime * RAND(1) * 10
,old_t = emptime
WHERE empno = '200000')
ORDER BY 1;
Figure 189, Select values - before and after update
indianZombie | www.indianzombie.blogspot.com 43
,actno AS act 000030 KWAN IF1000 10
FROM OLD TABLE
(DELETE
FROM emp_act_copy
WHERE empno < '0001')
ORDER BY 1,2,3
FETCH FIRST 5 ROWS ONLY;
Figure 192, Join result to another table
indianZombie | www.indianzombie.blogspot.com 44
MERGE INTO old_staff oo AFTER-MERGE
USING new_staff nn =================
ON oo.id = nn.id ID JOB SALARY
WHEN MATCHED THEN -- ----- --------
DELETE; 20 Sales 78171.25
Figure 196, Merge - delete if match
indianZombie | www.indianzombie.blogspot.com 45
SELECT MAX(id) + 1 AS max_id
,MAX(job) AS max_job
,MAX(salary) AS max_sal
FROM old_staff;
Figure 199, Merge logic - done using insert
BEGIN ATOMIC
DECLARE cntr SMALLINT DEFAULT 1;
FOR V1 AS
SELECT id as idval
indianZombie | www.indianzombie.blogspot.com 46
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 203, Sample Compound SQL statement
--#SET DELIMITER !
--#SET DELIMITER ;
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 205, DECLARE examples
indianZombie | www.indianzombie.blogspot.com 47
WHERE years < 4 230 83369.80 189.65
GROUP BY years 330 49988.00 55.50
ORDER BY years
DO
UPDATE staff AFTER
SET salary = salary / 10 ====================
WHERE id = max_id; ID SALARY COMM
UPDATE staff --- --------- ------
set comm = 0 180 37009.75 0.00
WHERE years = yr_num; 230 8336.98 0.00
END FOR; 330 4998.80 0.00
END
Figure 207, 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 209, GET DIAGNOSTICS statement example
BEGIN ATOMIC
DECLARE cur INT;
SET cur = MICROSECOND(CURRENT TIMESTAMP);
IF cur > 600000 THEN
UPDATE staff
SET name = CHAR(cur)
WHERE id = 10;
ELSEIF cur > 300000 THEN
UPDATE staff
SET name = CHAR(cur)
WHERE id = 20;
indianZombie | www.indianzombie.blogspot.com 48
ELSE
UPDATE staff
SET name = CHAR(cur)
WHERE id = 30;
END IF;
END
Figure 211, IF statement example
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 213, 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
indianZombie | www.indianzombie.blogspot.com 49
Figure 215, 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 217, 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 219, WHILE statement example
indianZombie | www.indianzombie.blogspot.com 50
ORDER BY dept; 10 4
15 4
20 4
38 5
42 4
51 5
66 5
84 4
Figure 220, List departments in STAFF table
indianZombie | www.indianzombie.blogspot.com 51
CREATE FUNCTION dpt1 (deptin SMALLINT) This example
RETURNS SMALLINT uses an "!"
BEGIN ATOMIC as the stmt
DECLARE num_names SMALLINT; delimiter.
FOR getnames AS
SELECT COUNT(*) AS #n
FROM staff
WHERE dept = deptin
DO
SET num_names = #n;
END FOR; ANSWER
RETURN num_names; ===========
END! DEPT #NAMES
COMMIT! ---- ------
10 4
SELECT XXX.* 15 4
,dpt1(dept) as #names 20 4
FROM (SELECT dept 38 5
FROM staff 42 4
GROUP BY dept 51 5
)AS XXX 66 5
ORDER BY dept! 84 4
Figure 222, Scalar Function with compound SQL
SELECT XXX.*
,dpt1(dept) as #names
FROM (SELECT dept
FROM staff
GROUP BY dept
)AS XXX
ORDER BY dept!
Figure 223, Scalar Function with compound SQL
indianZombie | www.indianzombie.blogspot.com 52
,#names SMALLINT) as the stmt
BEGIN ATOMIC delimiter.
RETURN
SELECT dept
,count(*) ANSWER
FROM staff ===========
GROUP BY dept DEPT #NAMES
ORDER BY dept; ---- ------
END! 10 4
COMMIT! 15 4
20 4
--#SET DELIMITER ; 38 5
42 4
SELECT * 51 5
FROM TABLE(dpt2()) T1 66 5
ORDER BY dept; 84 4
Figure 224, Table Function with compound SQL
UPDATE staff
SET comm = 0
WHERE comm IS NULL;
indianZombie | www.indianzombie.blogspot.com 53
FROM staff;
UPDATE staff
SET comm = NULL
WHERE comm = 0;
Figure 228, Convert zero to null before doing AVG
indianZombie | www.indianzombie.blogspot.com 54
UNION ALL COR11 COR12 COR23 COR34
SELECT col1 + 1 ------ ------ ------ ------
,col2 - 1 1.000 -1.000 -0.017 -0.005
,RAND()
,RAND()
FROM temp1
WHERE col1 <= 1000
)
SELECT DEC(CORRELATION(col1,col1),5,3) AS cor11
,DEC(CORRELATION(col1,col2),5,3) AS cor12
,DEC(CORRELATION(col2,col3),5,3) AS cor23
,DEC(CORRELATION(col3,col4),5,3) AS cor34
FROM temp1;
Figure 233, CORRELATION function examples
indianZombie | www.indianzombie.blogspot.com 55
SELECT COUNT_BIG(*) AS c1 ANSWER
,COUNT_BIG(dept) AS c2 ===================
,COUNT_BIG(DISTINCT dept) AS c3 C1 C2 C3 C4 C5
,COUNT_BIG(DISTINCT dept/10) AS c4 --- --- --- --- ---
,COUNT_BIG(DISTINCT dept)/10 AS c5 35. 35. 8. 7. 0.
FROM STAFF;
Figure 238, COUNT_BIG function examples
indianZombie | www.indianzombie.blogspot.com 56
51 83218.16 0
66 73015.24 0
84 66536.75 0
- 67932.78 1
Figure 242, GROUPING function example
indianZombie | www.indianzombie.blogspot.com 57
Figure 248, MIN function syntax
ANSWERS
==========
SELECT DEC(REGR_SLOPE(bonus,salary) ,7,5) AS r_slope 0.00247
,DEC(REGR_INTERCEPT(bonus,salary),7,3) AS r_icpt 644.862
,INT(REGR_COUNT(bonus,salary) ) AS r_count 5
,INT(REGR_AVGX(bonus,salary) ) AS r_avgx 70850
,INT(REGR_AVGY(bonus,salary) ) AS r_avgy 820
,DEC(REGR_SXX(bonus,salary) ,10) AS r_sxx 8784575000
,INT(REGR_SXY(bonus,salary) ) AS r_sxy 21715000
,INT(REGR_SYY(bonus,salary) ) AS r_syy 168000
FROM employee
WHERE workdept = 'A00';
Figure 251, REGRESSION functions examples
ANSWER
===============================
A1 S1 S2 S3 S4
-- ------------- ---- ---- ----
SELECT AVG(dept) AS a1 41 +2.3522355E+1 23.5 23.5 24.1
,STDDEV(dept) AS s1
,DEC(STDDEV(dept),3,1) AS s2
indianZombie | www.indianzombie.blogspot.com 58
,DEC(STDDEV(ALL dept),3,1) AS s3
,DEC(STDDEV(DISTINCT dept),3,1) AS s4
FROM staff;
Figure 253, STDDEV function examples
ANSWER
==============================
A1 V1 V2 V3 V4
-- --------------- --- --- ---
SELECT AVG(dept) AS a1 41 +5.533012244E+2 553 553 582
,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 257, VARIANCE function examples
indianZombie | www.indianzombie.blogspot.com 59
SELECT s1.job, s1.id, s1.salary
,SUM(salary) OVER(ORDER BY job, id) AS sumsal
,ROW_NUMBER() OVER(ORDER BY job, id) AS r ANSWER
FROM staff s1 ======
WHERE s1.name LIKE '%s%' JOB ID SALARY SUMSAL R
AND s1.id < 90 ----- -- -------- --------- -
ORDER BY s1.job Clerk 80 43504.60 43504.60 1
,s1.id; Mgr 10 98357.50 141862.10 2
Mgr 50 80659.80 222521.90 3
Figure 259, Using OLAP functions to get additional fields
indianZombie | www.indianzombie.blogspot.com 60
,DEC(AVG(salary) OVER(PARTITION BY dept
ORDER BY id
ROWS BETWEEN 1 PRECEDING
AND 2 FOLLOWING) ,8,2) AS avg4
FROM staff
WHERE dept IN (15,20)
AND id > 20
ORDER BY dept ,id;
ANSWER
=====================================================
DEPT ID SALARY AVG1 AVG2 AVG3 AVG4
---- --- -------- -------- -------- -------- --------
15 50 80659.80 53281.11 60482.33 80659.80 66556.94
15 70 76502.83 53281.11 60482.33 78581.31 60482.33
15 110 42508.20 53281.11 60482.33 66556.94 53756.51
15 170 42258.50 53281.11 60482.33 60482.33 42383.35
20 80 43504.60 53281.11 38878.67 43504.60 38878.67
20 190 34252.75 53281.11 38878.67 38878.67 38878.67
Figure 262, Sample OLAP query
indianZombie | www.indianzombie.blogspot.com 61
,AVG(years) AS avg DEPT SUM AVG ROW
,COUNT(*) 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
GROUP BY dept;
Figure 265, Sample query using GROUP BY
SELECT id ,salary
,DEC(AVG(salary) OVER() ,7,2) AS avg_all
,DEC(AVG(salary) OVER(ORDER BY id) ,7,2) AS avg_odr
,DEC(AVG(salary) OVER(ORDER BY id
ROWS BETWEEN UNBOUNDED PRECEDING
AND UNBOUNDED FOLLOWING) ,7,2) AS avg_p_f
,DEC(AVG(salary) OVER(ORDER BY id
ROWS BETWEEN UNBOUNDED PRECEDING
indianZombie | www.indianzombie.blogspot.com 62
AND CURRENT ROW) ,7,2) AS avg_p_c
,DEC(AVG(salary) OVER(ORDER BY id
ROWS BETWEEN CURRENT ROW
AND UNBOUNDED FOLLOWING) ,7,2) AS avg_c_f
,DEC(AVG(salary) OVER(ORDER BY id
ROWS BETWEEN 2 PRECEDING
AND 1 FOLLOWING) ,7,2) AS avg_2_1
FROM staff
WHERE dept IN (15,20)
AND id > 20
ORDER BY id;
ANSWER
==================================================================
ID SALARY AVG_ALL AVG_ODR AVG_P_F AVG_P_C AVG_C_F AVG_2_1
--- -------- -------- -------- -------- -------- -------- --------
50 80659.80 53281.11 80659.80 53281.11 80659.80 53281.11 78581.31
70 76502.83 53281.11 78581.31 53281.11 78581.31 47805.37 66889.07
80 43504.60 53281.11 66889.07 53281.11 66889.07 40631.01 60793.85
110 42508.20 53281.11 60793.85 53281.11 60793.85 39673.15 51193.53
170 42258.50 53281.11 57086.78 53281.11 57086.78 38255.62 40631.01
190 34252.75 53281.11 53281.11 53281.11 53281.11 34252.75 39673.15
Figure 269, Different window sizes
SELECT id
,SUM(id) OVER(ORDER BY id) AS sum1
,SUM(id) OVER(ORDER BY id ROWS 1 PRECEDING) AS sum2
,SUM(id) OVER(ORDER BY id ROWS UNBOUNDED PRECEDING) AS sum3
,SUM(id) OVER(ORDER BY id ROWS CURRENT ROW) AS sum4
,SUM(id) OVER(ORDER BY id ROWS 2 FOLLOWING) AS sum5
,SUM(id) OVER(ORDER BY id ROWS UNBOUNDED FOLLOWING) AS sum6
FROM staff
WHERE id < 40 ANSWER
ORDER BY id; ================================
ID SUM1 SUM2 SUM3 SUM4 SUM5 SUM6
-- ---- ---- ---- ---- ---- ----
10 10 10 10 10 60 60
20 30 30 30 20 50 50
30 60 50 60 30 30 30
Figure 270, Different window sizes
SELECT id
,SMALLINT(SUM(id) OVER(ORDER BY id
RANGE BETWEEN 10 PRECEDING AND 10 FOLLOWING)) AS rng1
,SMALLINT(SUM(id) OVER(ORDER BY id
ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING)) AS row1
,SMALLINT(SUM(id) OVER(ORDER BY id
RANGE BETWEEN 10 PRECEDING AND CURRENT ROW)) AS rng2
,SMALLINT(SUM(id) OVER(ORDER BY id
ROWS BETWEEN 3 PRECEDING AND 1 PRECEDING)) AS row2
indianZombie | www.indianzombie.blogspot.com 63
,SMALLINT(SUM(id) OVER(ORDER BY id DESC
ROWS BETWEEN 3 PRECEDING AND 1 PRECEDING)) AS row3
,SMALLINT(SUM(id) OVER(ORDER BY id
RANGE BETWEEN UNBOUNDED PRECEDING
AND 20 FOLLOWING)) AS rng3
FROM staff
WHERE id < 60
ORDER BY id; ANSWER
================================
ID RNG1 ROW1 RNG2 ROW2 ROW3 RNG3
-- ---- ---- ---- ---- ---- ----
10 30 30 10 - 90 60
20 60 60 30 10 120 100
30 90 90 50 30 90 150
40 120 120 70 60 50 150
50 90 90 90 90 - 150
Figure 271, ROW vs. RANGE example
ANSWER
================================================================
DEPT NAME SALARY SUM1 SUM2 SUM3 R1 R2 W1 W2
---- -------- -------- --------- --------- --------- -- -- -- --
15 Hanes 80659.80 80659.80 412701.30 80659.80 4 1 4 4
20 Pernal 78171.25 257188.55 332041.50 158831.05 3 2 3 3
20 Sanders 98357.50 257188.55 332041.50 257188.55 5 3 5 5
38 Marenghi 77506.75 412701.30 155512.75 334695.30 1 4 1 1
38 O'Brien 78006.00 412701.30 155512.75 412701.30 2 5 2 2
Figure 273, ORDER BY example
indianZombie | www.indianzombie.blogspot.com 64
SELECT id
,years AS yr
,salary
,DENSE_RANK() OVER(ORDER BY years ASC) AS a
,DENSE_RANK() OVER(ORDER BY years ASC NULLS FIRST) AS af
,DENSE_RANK() OVER(ORDER BY years ASC NULLS LAST ) AS al
,DENSE_RANK() OVER(ORDER BY years DESC) AS d
,DENSE_RANK() OVER(ORDER BY years DESC NULLS FIRST) AS df
,DENSE_RANK() OVER(ORDER BY years DESC NULLS LAST ) AS dl
FROM staff
WHERE id < 100
ORDER BY years
,salary; ANSWER
==================================
ID YR SALARY A AF AL D DF DL
-- -- -------- -- -- -- -- -- --
30 5 77506.75 1 2 1 6 6 5
90 6 38001.75 2 3 2 5 5 4
40 6 78006.00 2 3 2 5 5 4
70 7 76502.83 3 4 3 4 4 3
10 7 98357.50 3 4 3 4 4 3
20 8 78171.25 4 5 4 3 3 2
50 10 80659.80 5 6 5 2 2 1
80 - 43504.60 6 1 6 1 1 6
60 - 66808.30 6 1 6 1 1 6
Figure 274, Overriding the default null ordering sequence
SELECT id
indianZombie | www.indianzombie.blogspot.com 65
,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#
FROM staff
WHERE id < 100 ANSWER
AND years < 10 ===================================
ORDER BY years; ID YEARS SALARY RANK# DENSE# ROW#
-- ----- -------- ----- ------ ----
30 5 77506.75 1 1 1
40 6 78006.00 2 2 2
90 6 38001.75 2 2 3
10 7 98357.50 4 3 4
70 7 76502.83 4 3 5
20 8 78171.25 6 4 6
Figure 277, Ranking functions example
SELECT id ANSWER
,years AS yr =================
,salary ID YR SALARY R1
,RANK() OVER(PARTITION BY years -- -- -------- --
ORDER BY salary) AS r1 30 5 77506.75 1
indianZombie | www.indianzombie.blogspot.com 66
FROM staff 40 6 78006.00 1
WHERE id < 80 70 7 76502.83 1
AND years IS NOT NULL 10 7 98357.50 2
ORDER BY years 20 8 78171.25 1
,salary; 50 0 80659.80 1
Figure 279, Values ranked by subset of rows
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 280, Multiple rankings in same query
SELECT id
,years
,name
,salary
,SMALLINT(RANK() OVER(ORDER BY SUBSTR(name,3,2))) AS dumb1
,SMALLINT(RANK() OVER(ORDER BY salary / 1000)) AS dumb2
,SMALLINT(RANK() OVER(ORDER BY years * ID)) AS dumb3
,SMALLINT(RANK() OVER(ORDER BY 1)) AS dumb4
FROM staff
WHERE id < 40
AND years IS NOT NULL
ORDER BY 1;
Figure 281, Dumb rankings, SQL
indianZombie | www.indianzombie.blogspot.com 67
,RANK()OVER(ORDER BY id) AS r2 ================
FROM (SELECT id ID NAME R1 R2
,name -- ------- -- --
,RANK() OVER(ORDER BY id) AS r1 40 O'Brien 4 1
FROM staff 50 Hanes 5 2
WHERE id < 100 70 Rothman 6 3
AND years IS NOT NULL 90 Koonitz 7 4
)AS xxx
WHERE id > 30
ORDER BY id;
Figure 283, 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 10 1 98357.50 20
FROM staff 50 1 80659.80 15
WHERE id < 80 40 1 78006.00 38
AND years IS NOT NULL 20 2 78171.25 20
ORDER BY r1 ASC 30 2 77506.75 38
,salary DESC; 70 2 76502.83 15
Figure 284, Ordering rows by rank, using RANK function
SELECT id ANSWER
,(SELECT COUNT(*) =================
FROM staff s2 ID R1 SALARY DP
WHERE s2.id < 80 -- -- -------- --
AND S2.YEARS IS NOT NULL 10 1 98357.50 20
AND s2.dept = s1.dept 50 1 80659.80 15
AND s2.salary >= s1.salary) AS R1 40 1 78006.00 38
,SALARY 20 2 78171.25 20
,dept AS dp 30 2 77506.75 38
FROM staff s1 70 2 76502.83 15
WHERE id < 80
AND years IS NOT NULL
ORDER BY r1 ASC
,salary DESC;
Figure 285, Ordering rows by rank, using sub-query
SELECT id ANSWER
,salary ==============
,dept AS dp ID SALARY DP
FROM (SELECT s1.* -- -------- --
,RANK() OVER(PARTITION BY dept 50 80659.80 15
indianZombie | www.indianzombie.blogspot.com 68
ORDER BY salary DESC) AS r1 10 98357.50 20
FROM staff s1 40 78006.00 38
WHERE id < 80
AND years IS NOT NULL
)AS xxx
WHERE r1 = 1
ORDER BY dp;
Figure 286, 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 80659.80 15
AND years IS NOT NULL 10 98357.50 20
AND NOT EXISTS 40 78006.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 287, 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 80659.80 15
AND years IS NOT NULL 10 98357.50 20
AND (dept, salary) IN 40 78006.00 38
(SELECT dept, MAX(salary)
FROM staff
WHERE id < 80
AND years IS NOT NULL
GROUP BY dept)
ORDER BY dp;
Figure 288, Get highest salary in each department, use uncorrelated
sub-query
indianZombie | www.indianzombie.blogspot.com 69
SELECT id ANSWER
,name =================
,ROW_NUMBER() OVER() AS r1 ID NAME R1 R2
,ROW_NUMBER() OVER(ORDER BY id) AS r2 -- -------- -- --
FROM staff 10 Sanders 1 1
WHERE id < 50 20 Pernal 2 2
AND years IS NOT NULL 30 Marenghi 3 3
ORDER BY id; 40 O'Brien 4 4
Figure 290, ORDER BY example, 1 of 3
SELECT id ANSWER
,name =================
,ROW_NUMBER() OVER() AS r1 ID NAME R1 R2
,ROW_NUMBER() OVER(ORDER BY name) AS r2 -- -------- -- --
FROM staff 10 Sanders 4 4
WHERE id < 50 20 Pernal 3 3
AND years IS NOT NULL 30 Marenghi 1 1
ORDER BY id; 40 O'Brien 2 2
Figure 291, ORDER BY example, 2 of 3
SELECT id ANSWER
,name ====================
,ROW_NUMBER() OVER() AS r1 ID NAME R1 R2 R3
,ROW_NUMBER() OVER(ORDER BY ID) AS r2 -- -------- -- -- --
,ROW_NUMBER() OVER(ORDER BY NAME) AS r3 10 Sanders 1 1 4
FROM staff 20 Pernal 2 2 3
WHERE id < 50 30 Marenghi 3 3 1
AND years IS NOT NULL 40 O'Brien 4 4 2
ORDER BY id;
Figure 292, 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 ANSWER
AND years IN (6,7) ======================================
AND job > 'L' JOB YEARS ID NAME ROW# RN1# RN2#
indianZombie | www.indianzombie.blogspot.com 70
ORDER BY job ----- ----- --- ------- ---- ---- ----
,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 293, Use of PARTITION phrase
SELECT * ANSWER
FROM (SELECT id =============
,name ID NAME R
,ROW_NUMBER() OVER(ORDER BY id) AS r -- -------- -
FROM staff 10 Sanders 1
WHERE id < 100 20 Pernal 2
AND years IS NOT NULL 30 Marenghi 3
)AS xxx
WHERE r <= 3
ORDER BY id;
Figure 294, 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 295, Select first 3 rows, using FETCH FIRST notation
SELECT * ANSWER
FROM (SELECT id =============
,name ID NAME R
,ROW_NUMBER() OVER(ORDER BY id) AS r -- -------- -
FROM staff 30 Marenghi 3
WHERE id < 200 40 O'Brien 4
AND years IS NOT NULL 50 Hanes 5
)AS xxx 70 Rothman 6
WHERE r BETWEEN 3 AND 6
ORDER BY id;
Figure 296, Select 3rd through 6th rows
indianZombie | www.indianzombie.blogspot.com 71
SELECT * ANSWER
FROM (SELECT id ==============
,name ID NAME R
,ROW_NUMBER() OVER(ORDER BY id) AS r --- ------- --
FROM staff 10 Sanders 1
WHERE id < 200 70 Rothman 6
AND years IS NOT NULL 140 Fraye 11
)AS xxx 190 Sneider 16
WHERE (r - 1) = ((r - 1) / 5) * 5
ORDER BY id;
Figure 297, Select every 5th matching row
SELECT *
FROM (SELECT id
,name
,ROW_NUMBER() OVER(ORDER BY id DESC) AS r
FROM staff ANSWER
WHERE id < 200 ==============
AND years IS NOT NULL ID NAME R
)AS xxx --- -------- -
WHERE r <= 2 180 Abrahams 2
ORDER BY id; 190 Sneider 1
Figure 298, Select last two rows
SELECT *
FROM (SELECT years
,id
,name
,RANK() OVER(ORDER BY years) AS rnk
,ROW_NUMBER() OVER(ORDER BY years, id) AS row
FROM staff
WHERE id < 200 ANSWER
AND years IS NOT NULL ==========================
)AS xxx YEARS ID NAME RNK ROW
WHERE rnk <= 3 ----- --- -------- --- ---
ORDER BY years 3 180 Abrahams 1 1
,id; 4 170 Kermisch 2 2
5 30 Marenghi 3 3
5 110 Ngan 3 4
Figure 299, Select first "n" rows, or more if needed
indianZombie | www.indianzombie.blogspot.com 72
,customer# INTEGER NOT NULL
,sale_date DATE NOT NULL
,sale_value DECIMAL(9,2) NOT NULL
,CONSTRAINT ctx1 PRIMARY KEY (inv#)
,CONSTRAINT ctx2 CHECK(inv# >= 0));
Figure 300, Performance test table - definition
SELECT s.*
FROM invoice s
ORDER BY inv#
FETCH FIRST 5 ROWS ONLY;
Figure 302, Fetch first 5 rows - 0.000 elapsed seconds
SELECT s.*
FROM invoice s
ORDER BY inv#
FETCH FIRST 5 ROWS ONLY
OPTIMIZE FOR 5 ROWS;
Figure 303, Fetch first 5 rows - 0.000 elapsed seconds
SELECT s.*
,ROW_NUMBER() OVER() AS row#
FROM invoice s
ORDER BY inv#
FETCH FIRST 5 ROWS ONLY;
Figure 304, Fetch first 5 rows+ number rows - 0.000 elapsed seconds
indianZombie | www.indianzombie.blogspot.com 73
SELECT *
FROM (SELECT s.*
,ROW_NUMBER() OVER() AS row#
FROM invoice s
)xxx
ORDER BY inv#
FETCH FIRST 5 ROWS ONLY;
Figure 305, Fetch first 5 rows+ number rows - 0.000 elapsed seconds
SELECT *
FROM (SELECT s.*
,ROW_NUMBER() OVER() AS row#
FROM invoice s
)xxx
WHERE row# <= 5
ORDER BY inv#;
Figure 306, Process and number all rows - 0.049 elapsed seconds
SELECT *
FROM (SELECT s.*
,ROW_NUMBER() OVER(ORDER BY inv#) AS row#
FROM invoice s
)xxx
WHERE row# <= 5
ORDER BY inv#;
Figure 307, Process and number 5 rows only - 0.000 elapsed seconds
indianZombie | www.indianzombie.blogspot.com 74
AND new.inv# =
(SELECT MIN(xxx.inv#)
FROM invoice xxx
WHERE xxx.inv# > old.inv#)
)
SELECT *
FROM temp;
Figure 308, Fetch first 5 rows - 0.000 elapsed seconds
indianZombie | www.indianzombie.blogspot.com 75
15 50 - 1152.00 - 1152.00 1152.00 - 1152.00
20 80 128.20 128.20 - 128.20 128.20 128.20 612.45
20 20 612.45 128.20 - 128.20 128.20 612.45 612.45
20 10 - 128.20 - 128.20 612.45 - 612.45
Figure 311, Function examples
indianZombie | www.indianzombie.blogspot.com 76
---- --- ------- ------- ------- ------- ------- -------
10 160 - - - - -1.00 -
15 110 206.60 - 206.60 - -1.00 1152.00
15 70 1152.00 206.60 1152.00 - 206.60 -
15 50 - 1152.00 - 206.60 1152.00 -
20 80 128.20 - 128.20 - -1.00 612.45
20 20 612.45 128.20 612.45 - 128.20 -
Figure 314, LAG and LEAD function Examples
SELECT id
,name
,salary
,SUM(salary) OVER() AS sum1
,SUM(salary) OVER(ORDER BY id * 0) AS sum2
,SUM(salary) OVER(ORDER BY 'ABC') AS sum3
,SUM(salary) OVER(ORDER BY 'ABC'
RANGE BETWEEN UNBOUNDED PRECEDING
AND UNBOUNDED FOLLOWING) AS sum4
FROM staff
WHERE id < 60
ORDER BY id;
ANSWER
============================================================
ID NAME SALARY SUM1 SUM2 SUM3 SUM4
indianZombie | www.indianzombie.blogspot.com 77
-- -------- -------- --------- --------- --------- ---------
10 Sanders 98357.50 412701.30 412701.30 412701.30 412701.30
20 Pernal 78171.25 412701.30 412701.30 412701.30 412701.30
30 Marenghi 77506.75 412701.30 412701.30 412701.30 412701.30
40 O'Brien 78006.00 412701.30 412701.30 412701.30 412701.30
50 Hanes 80659.80 412701.30 412701.30 412701.30 412701.30
Figure 317, Logically equivalent aggregation functions
SELECT dept
,name
,salary
,SUM(salary) OVER(ORDER BY dept) AS sum1
,SUM(salary) OVER(ORDER BY dept DESC) AS sum2
,SUM(salary) OVER(ORDER BY dept, NAME) AS sum3
,SUM(salary) OVER(ORDER BY dept DESC, name DESC) AS sum4
,COUNT(*) OVER(ORDER BY dept) AS rw1
,COUNT(*) OVER(ORDER BY dept, NAME) AS rw2
FROM staff
WHERE id < 60
ORDER BY dept
,name;
ANSWER
======================================================================
DEPT NAME SALARY SUM1 SUM2 SUM3 SUM4 RW1 RW2
---- -------- -------- --------- --------- --------- --------- --- ---
15 Hanes 80659.80 80659.80 412701.30 80659.80 412701.30 1 1
20 Pernal 78171.25 257188.55 332041.50 158831.05 332041.50 3 2
20 Sanders 98357.50 257188.55 332041.50 257188.55 253870.25 3 3
38 Marenghi 77506.75 412701.30 155512.75 334695.30 155512.75 5 4
38 O'Brien 78006.00 412701.30 155512.75 412701.30 78006.00 5 5
Figure 318, Aggregation function, ORDER BY usage
SELECT id ,years
,AVG(years) OVER() AS "p_f"
,AVG(years) OVER(ORDER BY id
ROWS BETWEEN UNBOUNDED PRECEDING
AND UNBOUNDED FOLLOWING) AS "p_f"
,AVG(years) OVER(ORDER BY id) AS "p_c"
,AVG(years) OVER(ORDER BY id
ROWS BETWEEN UNBOUNDED PRECEDING
AND CURRENT ROW) AS "p_c"
,AVG(years) OVER(ORDER BY id
ROWS UNBOUNDED PRECEDING) AS "p_c"
,AVG(years) OVER(ORDER BY id
ROWS UNBOUNDED FOLLOWING) AS "c_f"
,AVG(years) OVER(ORDER BY id
ROWS 2 FOLLOWING) AS "c_2"
,AVG(years) OVER(ORDER BY id
indianZombie | www.indianzombie.blogspot.com 78
ROWS 1 PRECEDING) AS "1_c"
,AVG(years) OVER(ORDER BY id
ROWS BETWEEN 1 FOLLOWING
AND 2 FOLLOWING) AS "1_2"
FROM staff
WHERE dept IN (15,20)
AND id > 20 ANSWER
AND years > 1 =============================================
ORDER BY id; ID YEARS p_f p_f p_c p_c p_c c_f c_2 1_c 1_2
--- ----- --- --- --- --- --- --- --- --- ---
50 10 6 6 10 10 10 6 7 10 6
70 7 6 6 8 8 8 6 5 8 4
110 5 6 6 7 7 7 5 5 6 6
170 4 6 6 6 6 6 6 6 4 8
190 8 6 6 6 6 6 8 8 6 -
Figure 319, ROWS usage examples
SELECT dept
,name
,years
,SMALLINT(SUM(years) OVER(ORDER BY dept
ROWS BETWEEN 1 PRECEDING
AND CURRENT ROW)) AS row1
,SMALLINT(SUM(years) OVER(ORDER BY dept
ROWS BETWEEN 2 PRECEDING
AND CURRENT ROW)) AS row2
,SMALLINT(SUM(years) OVER(ORDER BY dept
RANGE BETWEEN 1 PRECEDING
AND CURRENT ROW)) AS rg01
,SMALLINT(SUM(years) OVER(ORDER BY dept
RANGE BETWEEN 10 PRECEDING
AND CURRENT ROW)) AS rg10
,SMALLINT(SUM(years) OVER(ORDER BY dept
RANGE BETWEEN 20 PRECEDING
AND CURRENT ROW)) AS rg20
,SMALLINT(SUM(years) OVER(ORDER BY dept
RANGE BETWEEN 10 PRECEDING
AND 20 FOLLOWING)) AS rg11
,SMALLINT(SUM(years) OVER(ORDER BY dept
RANGE BETWEEN CURRENT ROW
AND 20 FOLLOWING)) AS rg99
FROM staff
WHERE id < 100
AND years IS NOT NULL
ORDER BY dept
,name;
ANSWER
=======================================================
DEPT NAME YEARS ROW1 ROW2 RG01 RG10 RG20 RG11 RG99
------ ------- ----- ---- ---- ---- ---- ---- ---- ----
15 Hanes 10 10 10 17 17 17 32 32
15 Rothman 7 17 17 17 17 17 32 32
20 Pernal 8 15 25 15 32 32 43 26
indianZombie | www.indianzombie.blogspot.com 79
20 Sanders 7 15 22 15 32 32 43 26
38 Marengh 5 12 20 11 11 26 17 17
38 O'Brien 6 11 18 11 11 26 17 17
42 Koonitz 6 12 17 6 17 17 17 6
Figure 320, RANGE usage
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 321,BETWEEN and ORDER BY usage
ASC id (10,20,30,40)
READ ROWS, LEFT to RIGHT 1ST-ROW 2ND-ROW 3RD-ROW 4TH-ROW
========================== ======== ======== ======== ========
1 PRECEDING to CURRENT ROW 10=10 10+20=30 20+30=40 30+40=70
CURRENT ROW to 1 FOLLOWING 10+20=30 20+30=50 30+40=70 40 =40
DESC id (40,30,20,10)
READ ROWS, RIGHT to LEFT 1ST-ROW 2ND-ROW 3RD-ROW 4TH-ROW
========================== ======== ======== ======== ========
1 PRECEDING to CURRENT ROW 20+10=30 30+20=50 40+30=70 40 =40
CURRENT ROW to 1 FOLLOWING 10 =10 20+10=30 30+20=50 40+30=70
indianZombie | www.indianzombie.blogspot.com 80
CREATE VIEW scalar (d1,f1,s1,c1,v1,ts1,dt1,tm1,tc1) AS
WITH temp1 (n1, c1, t1) AS
(VALUES (-2.4,'ABCDEF','1996-04-22-23.58.58.123456')
,(+0.0,'ABCD ','1996-08-15-15.15.15.151515')
,(+1.8,'AB ','0001-01-01-00.00.00.000000'))
SELECT DECIMAL(n1,3,1)
,DOUBLE(n1)
,SMALLINT(n1)
,CHAR(c1,6)
,VARCHAR(RTRIM(c1),6)
,TIMESTAMP(t1)
,DATE(t1)
,TIME(t1)
,CHAR(t1)
FROM temp1;
Figure 323, Sample View DDL - Scalar functions
D1 F1 S1 C1 V1 TS1
------ --------- -- ------ ------ --------------------------
-2.4 -2.4e+000 -2 ABCDEF ABCDEF 1996-04-22-23.58.58.123456
0.0 0.0e+000 0 ABCD ABCD 1996-08-15-15.15.15.151515
1.8 1.8e+000 1 AB AB 0001-01-01-00.00.00.000000
indianZombie | www.indianzombie.blogspot.com 81
SELECT c1 ANSWER
,ASCII(c1) AS ac1 ================
,ASCII(SUBSTR(c1,2)) AS ac2 C1 AC1 AC2
FROM scalar ------ --- ---
WHERE c1 = 'ABCDEF'; ABCDEF 65 66
Figure 326, ASCII function examples
indianZombie | www.indianzombie.blogspot.com 82
+1.23456789000000E+018 1234567890000000000. 1234567889999999488
Figure 329, Convert FLOAT to DECIMAL and BIGINT, answer
WITH ANSWER
temp1 (b1, b2) AS ===============================
(VALUES ( 1, 0) ,( 0, 1) B1 B2 hex1 hex2 and ano or xor
,( 0, 0) ,( 1, 1) -- -- ---- ---- --- --- --- ---
,( 2, 1) ,(15,-7) 1 0 0100 0000 0 1 1 1
,(15, 7) ,(-1, 1) 0 1 0000 0100 0 0 1 1
,(15,63) ,(63,31) 0 0 0000 0000 0 0 0 0
,(99,64) ,( 0,-2)), 1 1 0100 0100 1 0 1 0
temp2 (b1, b2) AS 2 1 0200 0100 0 2 3 3
(SELECT SMALLINT(b1) 15 -7 0F00 F9FF 9 6 -1 -10
,SMALLINT(b2) 15 7 0F00 0700 7 8 15 8
FROM temp1) -1 1 FFFF 0100 1 -2 -1 -2
SELECT b1 ,b2 15 63 0F00 3F00 15 0 63 48
,HEX(b1) AS "hex1" 63 31 3F00 1F00 31 32 63 32
,HEX(b2) AS "hex2" 99 64 6300 4000 64 35 99 35
,BITAND(b1,b2) AS "and" 0 -2 0000 FEFF 0 0 -2 -2
,BITANDNOT(b1,b2) AS "ano"
,BITOR(b1,b2) AS "or"
,BITXOR(b1,b2) AS "xor"
FROM temp2;
Figure 331, BIT functions examples
indianZombie | www.indianzombie.blogspot.com 83
WITH ANSWER
temp1 (b1) AS ============================
(VALUES (32767) ,(16383) B1 hex1 bit_display
,( 4096) ,( 118) ------ ---- ----------------
,( 63) ,( 16) 32767 FF7F 0111111111111111
,( 2) ,( 1) 16383 FF3F 0011111111111111
,( 0) ,( -1) 4096 0010 0001000000000000
,( -2) ,( -3) 118 7600 0000000001110110
,( -64) ,(-32768) 63 3F00 0000000000111111
), 16 1000 0000000000010000
temp2 (b1) AS 2 0200 0000000000000010
(SELECT SMALLINT(b1) 1 0100 0000000000000001
FROM temp1 0 0000 0000000000000000
) -1 FFFF 1111111111111111
SELECT b1 -2 FEFF 1111111111111110
,HEX(b1) AS "hex1" -3 FDFF 1111111111111101
,BITDISPLAY(b1) AS "bit_display" -64 C0FF 1111111111000000
FROM temp2; -32768 0080 1000000000000000
Figure 333, BIT_DISPLAY function example
WITH
temp1 (b1) AS
(VALUES (32767),(21845),( 4096),( 0),( -1),( -64)
),
temp2 (b1, s15) AS
(SELECT SMALLINT(b1)
,SMALLINT(15)
FROM temp1
)
SELECT b1
,BITDISPLAY(b1) AS "b1_display"
,BITXOR(b1,s15) AS "xor"
,BITDISPLAY(BITXOR(b1,s15)) AS "xor_display"
,BITANDNOT(b1,s15) AS "andnot"
,BITDISPLAY(BITANDNOT(b1,s15)) AS "andnot_display"
FROM temp2;
Figure 334, Update bits #1, query
indianZombie | www.indianzombie.blogspot.com 84
-1 1111111111111111 -16 1111111111110000 -16 1111111111110000
-64 1111111111000000 -49 1111111111001111 -64 1111111111000000
Figure 335, Update bits #1, answer
WITH
temp1 (b1) AS
(VALUES (32767),(21845),( 4096),( 0),( -1),( -64)
),
temp2 (b1, s15) AS
(SELECT SMALLINT(b1)
,SMALLINT(15)
FROM temp1
)
SELECT b1
,BITDISPLAY(b1) AS "b1_display"
,BITAND(b1,s15) AS "and"
,BITDISPLAY(BITAND(b1,s15)) AS "and_display"
,BITNOT(b1) AS "not"
,BITDISPLAY(BITNOT(b1)) AS "not_display"
FROM temp2;
Figure 336, Update bits #2, query
indianZombie | www.indianzombie.blogspot.com 85
,CEIL(d1) AS d2 ==================================
,f1 D1 D2 F1 F2
,CEIL(f1) AS f2 ---- ---- ---------- ----------
FROM scalar; -2.4 -2. -2.400E+0 -2.000E+0
0.0 0. +0.000E+0 +0.000E+0
1.8 2. +1.800E+0 +2.000E+0
Figure 340, CEIL function examples
ANSWER
==========================================
INT CHAR_INT CHAR_FLT CHAR_DEC
-------- -------- ----------- ------------
WITH temp1 (n) AS 3 3 3.0E0 00000000003.
(VALUES (3) 9 9 9.0E0 00000000009.
UNION ALL 81 81 8.1E1 00000000081.
SELECT n * n 6561 6561 6.561E3 00000006561.
FROM temp1 43046721 43046721 4.3046721E7 00043046721.
WHERE n < 9000
)
SELECT n AS int
,CHAR(INT(n)) AS char_int
,CHAR(FLOAT(n)) AS char_flt
,CHAR(DEC(n)) AS char_dec
FROM temp1;
Figure 343, CHAR function examples - positive numbers
indianZombie | www.indianzombie.blogspot.com 86
,SMALLINT(-7)) N1 I1 I2 D1 D2
UNION ALL ------ ----- ------ ------- -------
SELECT n1 * n2 3 3 +3 00003. +00003.
,n2 -21 -21 -21 -00021. -00021.
FROM temp1 147 147 +147 00147. +00147.
WHERE n1 < 300 -1029 -1029 -1029 -01029. -01029.
) 7203 7203 +7203 07203. +07203.
SELECT n1
,CHAR(n1) AS i1
,CASE
WHEN n1 < 0 THEN CHAR(n1)
ELSE '+' CONCAT CHAR(n1)
END AS i2
,CHAR(DEC(n1)) AS d1
,CASE
WHEN n1 < 0 THEN CHAR(DEC(n1))
ELSE '+' CONCAT CHAR(DEC(n1))
END AS d2
FROM temp1;
Figure 344, Align CHAR function output - numbers
ANSWER
==========
SELECT CHAR(CURRENT DATE,ISO) AS iso ==> 2005-11-30
,CHAR(CURRENT DATE,EUR) AS eur ==> 30.11.2005
,CHAR(CURRENT DATE,JIS) AS jis ==> 2005-11-30
,CHAR(CURRENT DATE,USA) AS usa ==> 11/30/2005
FROM sysibm.sysdummy1;
Figure 345, CHAR function examples - date value
ANSWER
========
SELECT CHAR(CURRENT TIME,ISO) AS iso ==> 19.42.21
,CHAR(CURRENT TIME,EUR) AS eur ==> 19.42.21
,CHAR(CURRENT TIME,JIS) AS jis ==> 19:42:21
,CHAR(CURRENT TIME,USA) AS usa ==> 07:42 PM
FROM sysibm.sysdummy1;
Figure 346, CHAR function examples - time value
indianZombie | www.indianzombie.blogspot.com 87
SELECT d2 ANSWER
,CHAR(d2) AS cd2 ================
,DIGITS(d2) AS dd2 D2 CD2 DD2
FROM (SELECT DEC(d1,4,1) AS d2 ---- ------ ----
FROM scalar -2.4 -002.4 0024
)AS xxx 0.0 000.0 0000
ORDER BY 1; 1.8 001.8 0018
Figure 348, DIGITS vs. CHAR
SELECT c1 ANSWER
,CLOB(c1) AS cc1 ===================
,CLOB(c1,3) AS cc2 C1 CC1 CC2
FROM scalar; ------ ------ ---
ABCDEF ABCDEF ABC
ABCD ABCD ABC
AB AB AB
Figure 352, CLOB function examples
indianZombie | www.indianzombie.blogspot.com 88
SELECT id ANSWER
,comm ==================
,COALESCE(comm,0) ID COMM 3
FROM staff -- ------ ------
WHERE id < 30 10 - 0.00
ORDER BY id; 20 612.45 612.45
Figure 353, COALESCE function example
indianZombie | www.indianzombie.blogspot.com 89
(DECFLOAT(1234), -infinity) ,(+infinity, +infinity) DECFLOAT(-0.00)) ,
(DECFLOAT(-0.0), DECFLOAT(+0.00)) ,(DECFLOAT(+0.0), DECFLOAT(-1.00)) ,
(DECFLOAT(-1.0), DECFLOAT(+1.00)) ,(DECFLOAT(+1.0), DECFLOAT(+1.0))
(DECFLOAT(+1.0), d2) (d1, answer COLLATION_KEY_BIT 357, x?280105010500?
x?28010500? x?2800? b x?2601869D018F0500? x?2601869D00? x?2600? Ä x?
2601868D018F0500? x?2601868D00? Á x?260105018F00? x?26010500? x?
260105010500? a="A=Á=Ä" --------------------- a<A<Á 10;
---------- ----
1996-04-22 22
1996-08-15 15
Figure 366, DAY function examples
WITH ANSWER
temp1 (n) AS ========================
indianZombie | www.indianzombie.blogspot.com 90
(VALUES (0) DATE DAY W D WI I
UNION ALL ---------- --- -- - -- -
SELECT n+1 1999-12-25 Sat 52 7 51 6
FROM temp1 1999-12-26 Sun 53 1 51 7
WHERE n < 9), 1999-12-27 Mon 53 2 52 1
temp2 (dt1) AS 1999-12-28 Tue 53 3 52 2
(VALUES(DATE('1999-12-25')) 1999-12-29 Wed 53 4 52 3
,(DATE('2000-12-24'))), 1999-12-30 Thu 53 5 52 4
temp3 (dt2) AS 1999-12-31 Fri 53 6 52 5
(SELECT dt1 + n DAYS 2000-01-01 Sat 1 7 52 6
FROM temp1 2000-01-02 Sun 2 1 52 7
,temp2) 2000-01-03 Mon 2 2 1 1
SELECT CHAR(dt2,ISO) AS date 2000-12-24 Sun 53 1 51 7
,SUBSTR(DAYNAME(dt2),1,3) AS day 2000-12-25 Mon 53 2 52 1
,WEEK(dt2) AS w 2000-12-26 Tue 53 3 52 2
,DAYOFWEEK(dt2) AS d 2000-12-27 Wed 53 4 52 3
,WEEK_ISO(dt2) AS wi 2000-12-28 Thu 53 5 52 4
,DAYOFWEEK_ISO(dt2) AS i 2000-12-29 Fri 53 6 52 5
FROM temp3 2000-12-30 Sat 53 7 52 6
ORDER BY 1; 2000-12-31 Sun 54 1 52 7
2001-01-01 Mon 1 2 1 1
2001-01-02 Tue 1 3 1 2
Figure 370, DAYOFWEEK_ISO function example
indianZombie | www.indianzombie.blogspot.com 91
SELECT DBPARTITIONNUM(id) AS dbnum ANSWER
FROM staff ======
WHERE id = 10; DBNUM
-----
0
Figure 374, DBPARTITIONNUM function example
ANSWER
======
SELECT DECFLOAT(+123.4) 123.4
,DECFLOAT(1.0 ,16) 1.0
,DECFLOAT(1.0000 ,16) 1.0000
,DECFLOAT(1.2e-3 ,34) 0.0011999999999999999
,DECFLOAT('1.2e-3' ,34) 0.0012
,DECFLOAT(-1E3 ,34) -1000
,DECFLOAT('-1E3' ,34) -1E+3
,DECFLOAT('12.5' ,16) 12.5
,DECFLOAT('12#5' ,16, '#') 12.5
FROM sysibm.sysdummy1;
Figure 376, DECFLOAT function example
indianZombie | www.indianzombie.blogspot.com 92
SELECT firstnme ANSWER
,sex ===========================
,CASE sex FIRSTNME SEX SEX2 SEX3
WHEN 'F' THEN 'FEMALE' --------- --- ------ ------
WHEN 'M' THEN 'MALE' BRUCE M MALE MALE
ELSE '?' CHRISTINE F FEMALE FEMALE
END AS sex2
,DECODE(sex,'F','FEMALE','M','MALE','?') AS sex3
FROM employee
WHERE firstnme < 'D'
ORDER BY firstnme;
Figure 379, DECODE function example
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 381, DECRYPT_CHAR function example
indianZombie | www.indianzombie.blogspot.com 93
Figure 382, DIFFERENCE function example
SELECT s1 ANSWER
,DIGITS(s1) AS ds1 =========================
,d1 S1 DS1 D1 DD1
,DIGITS(d1) AS dd1 ------ ----- ----- ---
FROM scalar; -2 00002 -2.4 024
0 00000 0.0 000
1 00001 1.8 018
Figure 383, DIGITS function examples
SELECT id
,name
,ENCRYPT(name,'THAT IDIOT','MY BROTHER') AS name2
FROM staff
WHERE ID < 30
ORDER BY id;
Figure 386, ENCRYPT function example
indianZombie | www.indianzombie.blogspot.com 94
SELECT n1 2 +7.38905609893065E+0 7
,EXP(n1) AS e1 3 +2.00855369231876E+1 20
,SMALLINT(EXP(n1)) AS e2 4 +5.45981500331442E+1 54
FROM temp1; 5 +1.48413159102576E+2 148
6 +4.03428793492735E+2 403
7 +1.09663315842845E+3 1096
8 +2.98095798704172E+3 2980
9 +8.10308392757538E+3 8103
10 +2.20264657948067E+4 22026
Figure 387, EXP function examples
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 389, GENERATE_UNIQUE function examples
indianZombie | www.indianzombie.blogspot.com 95
SELECT u1
,SUBSTR(u1,20,1) CONCAT SUBSTR(u1,19,1) CONCAT
SUBSTR(u1,18,1) CONCAT SUBSTR(u1,17,1) CONCAT
SUBSTR(u1,16,1) CONCAT SUBSTR(u1,15,1) CONCAT
SUBSTR(u1,14,1) CONCAT SUBSTR(u1,13,1) CONCAT
SUBSTR(u1,12,1) CONCAT SUBSTR(u1,11,1) CONCAT
SUBSTR(u1,10,1) CONCAT SUBSTR(u1,09,1) CONCAT
SUBSTR(u1,08,1) CONCAT SUBSTR(u1,07,1) CONCAT
SUBSTR(u1,06,1) CONCAT SUBSTR(u1,05,1) CONCAT
SUBSTR(u1,04,1) CONCAT SUBSTR(u1,03,1) CONCAT
SUBSTR(u1,02,1) CONCAT SUBSTR(u1,01,1) AS U2
FROM (SELECT HEX(GENERATE_UNIQUE()) AS u1
FROM staff
WHERE id < 50) AS xxx
ORDER BY u2; ANSWER
================================================
U1 U2
-------------------------- --------------------
20000901131649119940000000 04991194613110900002
20000901131649119793000000 39791194613110900002
20000901131649119907000000 70991194613110900002
20000901131649119969000000 96991194613110900002
Figure 391, 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 392, 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
-- ------- ----------
indianZombie | www.indianzombie.blogspot.com 96
10 Sanders MY BROTHER
20 Pernal MY BROTHER
Figure 393, GETHINT function example
SELECT c1 ANSWER
,HEX(c1) AS chx =======================================
,v1 C1 CHX V1 VHX
,HEX(v1) AS vhx ------ ------------ ------ ------------
FROM scalar; ABCDEF 414243444546 ABCDEF 414243444546
ABCD 414243442020 ABCD 41424344
AB 414220202020 AB 4142
Figure 396, HEX function examples, character & varchar
indianZombie | www.indianzombie.blogspot.com 97
SELECT tm1 ANSWER
,HOUR(tm1) AS hr ============
FROM scalar TM1 HR
ORDER BY tm1; -------- --
00:00:00 0
15:15:15 15
23:58:58 23
Figure 398, HOUR function example
SELECT d1 ANSWER
indianZombie | www.indianzombie.blogspot.com 98
,INTEGER(d1) ====================================
,INT('+123') D1 2 3 4 5
,INT('-123') ----- ----- ------ ------ ------
,INT(' 123 ') -2.4 -2 123 -123 123
FROM scalar; 0.0 0 123 -123 123
1.8 1 123 -123 123
Figure 402, INTEGER function examples
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 404, JULIAN_DAY function examples
ANSWER
=============================
DT DJ1 DJ2
WITH temp1(dt1) AS ---------- ---------- -------
(VALUES ('2007-01-01') 2007-01-01 2006-12-19 2007001
,('2007-01-02') 2007-01-02 2006-12-20 2007002
,('2007-12-31')) 2007-12-31 2007-12-18 2007365
SELECT DATE(dt1) AS dt
indianZombie | www.indianzombie.blogspot.com 99
,DATE(dt1) - 13 DAYS AS dj1
,YEAR(dt1) * 1000 + DAYOFYEAR(dt1) AS dj2
FROM temp1;
Figure 405, Julian Date outputs
ANSWER
==============
MS TM
----- --------
WITH temp1 (ms) AS 0 00:00:00
(SELECT MIDNIGHT_SECONDS(ts1) 54915 15:15:15
FROM scalar 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 tm
FROM temp1
ORDER BY 1;
Figure 418, Convert MIDNIGHT_SECONDS output back to a time value
<--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 424, Decimal multiplication - same output lengths
ANSWER
===========================
D1 D2
WITH temp1 (d1) AS -------------------- ------
(VALUES (DECFLOAT(1)) 1 1
,(DECFLOAT(1.0)) 1.0 1
,(DECFLOAT(1.00)) 1.00 1
,(DECFLOAT(1.000)) 1.000 1
,(DECFLOAT('12.3')) 12.3 12.3
,(DECFLOAT('12.30')) 12.30 12.3
,(DECFLOAT(1.2e4)) 12000 1.2E+4
,(DECFLOAT('1.2e4')) 1.2E+4 1.2E+4
,(DECFLOAT(1.2e-3)) 0.001200000000000000 0.0012
,(DECFLOAT('1.2e-3')) 0.0012 0.0012
)
SELECT d1
,NORMALIZE_DECFLOAT(d1) AS d2
FROM temp1;
Figure 425, NORMALIZE_DECFLOAT function examples
SELECT s1 ANSWER
,NULLIF(s1,0) =====================
,c1 S1 2 C1 4
SELECT c1 ANSWER
,POSSTR(c1,' ') AS p1 ==================
,POSSTR(c1,'CD') AS p2 C1 P1 P2 P3
,POSSTR(c1,'cd') AS p3 ------ -- -- --
FROM scalar AB 3 0 0
ORDER BY 1; ABCD 5 3 0
ABCDEF 0 3 0
Figure 433, POSSTR function example
SELECT c1 ANSWER
,POSSTR(c1,' ') AS p1 ===========================
,LOCATE(' ',c1) AS l1 C1 P1 L1 P2 L2 P3 L3 L4
,POSSTR(c1,'CD') AS p2 ------ -- -- -- -- -- -- --
,LOCATE('CD',c1) AS l2 AB 3 3 0 0 0 0 0
,POSSTR(c1,'cd') AS p3 ABCD 5 5 3 3 0 0 4
,LOCATE('cd',c1) AS l3 ABCDEF 0 0 3 3 0 0 4
,LOCATE('D',c1,2) AS l4
FROM scalar
ORDER BY 1;
Figure 434, POSSTR vs. LOCATE functions
ANSWER
WITH temp1 (d1, d2) AS ------------------------
(VALUES (+1.23, DECFLOAT(1.0)) 1.2
,(+1.23, DECFLOAT(1.00)) 1.23
,(-1.23, DECFLOAT(1.000)) -1.230
,(+123, DECFLOAT(9.8765)) 123.0000
,(+123, DECFLOAT(1E-3)) 123.000
,(+123, DECFLOAT(1E+3)) 123
,(SQRT(2), DECFLOAT(0.0)) 1.4
,(SQRT(2), DECFLOAT('1E-5')) 1.41421
,(SQRT(2), DECFLOAT( 1E-5 )) 1.414213562373095100000
)
SELECT QUANTIZE(d1,d2)
FROM temp1;
Figure 436, QUANTIZE function examples
ANSWER
WITH temp1 (d1) AS -----------------------
(VALUES (DECFLOAT('1E-5')) 0.00001
,(DECFLOAT( 1E-5 )) 0.000010000000000000001
)
SELECT d1
FROM temp1;
Figure 437, DECFLOAT conversion example
SELECT s1 ANSWER
,CASE ==============
WHEN s1 < 1 THEN s1 S1 S2
ELSE RAISE_ERROR('80001',c1) ------ ------
END AS s2 -2 -2
FROM scalar; 0 0
SQLSTATE=80001
Figure 439, RAISE_ERROR function example
SELECT id ANSWER
,name ============
FROM staff ID NAME
WHERE RAND() < 0.1 --- --------
ORDER BY id; 140 Fraye
190 Sneider
290 Quill
Figure 445, Randomly select 10% of matching rows
SELECT id ANSWER
,name ============
UPDATE staff
SET salary = RAND()*10000
WHERE id < 50;
Figure 447, Use RAND to assign random salaries
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 448, REAL and other numeric function examples
SELECT id ANSWER
,CHAR(REPEAT(name,3),40) ===========================
FROM staff ID 2
WHERE id < 40 -- ------------------------
ORDER BY id; 10 SandersSandersSanders
20 PernalPernalPernal
30 MarenghiMarenghiMarenghi
Figure 450, REPEAT function example
SELECT c1 ANSWER
,REPLACE(c1,'AB','XY') AS r1 ======================
,REPLACE(c1,'BA','XY') AS r2 C1 R1 R2
FROM scalar; ------ ------ ------
ABCDEF XYCDEF ABCDEF
ABCD XYCD ABCD
AB XY AB
Figure 452, REPLACE function examples
SELECT c1 ANSWER
,REPLACE(REPLACE( ==============
REPLACE(REPLACE(c1, C1 R1
'AB','XY'),'ab','XY'), ------ ------
'Ab','XY'),'aB','XY') ABCDEF XYCDEF
FROM scalar; ABCD XYCD
AB XY
Figure 453, Nested REPLACE functions
SELECT id ANSWER
,salary =====================
,RID(staff) AS staff_rid ID SALARY STAFF_RID
FROM staff -- -------- ---------
WHERE id < 40 10 98357.50 100663300
ORDER BY id; 20 78171.25 100663301
30 77506.75 100663302
Figure 454, RID function example
ANSWER
===============================================
D1 P2 P1 P0 N1 N2
------- ------- ------- ------- ------- -------
WITH temp1(d1) AS 123.400 123.400 123.400 123.000 120.000 100.000
(VALUES (123.400) 23.450 23.450 23.400 23.000 20.000 0.000
,( 23.450) 3.456 3.460 3.500 3.000 0.000 0.000
,( 3.456) 0.056 0.060 0.100 0.000 0.000 0.000
,( .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 460, ROUND function examples
SELECT c1 ANSWER
,RTRIM(c1) AS r1 ======================
,LENGTH(c1) AS r2 C1 R1 R2 R3
,LENGTH(RTRIM(c1)) AS r3 ------ ------ -- --
FROM scalar; ABCDEF ABCDEF 6 6
ABCD ABCD 6 4
SELECT d1 ANSWER
,SMALLINT(d1) ==================================
,SMALLINT('+123') D1 2 3 4 5
,SMALLINT('-123') ----- ------ ------ ------ ------
,SMALLINT(' 123 ') -2.4 -2 123 -123 123
FROM scalar; 0.0 0 123 -123 123
1.8 1 123 -123 123
Figure 464, SMALLINT function examples
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
ANSWER
WITH temp1 (d1, d2) AS ======
(VALUES (DECFLOAT(+1.0), DECFLOAT(+1.0)) 0
,(DECFLOAT(+1.0), DECFLOAT(+1.00)) 1
,(DECFLOAT(-1.0), DECFLOAT(-1.00)) -1
,(DECFLOAT(+0.0), DECFLOAT(+0.00)) 1
,(DECFLOAT(-0.0), DECFLOAT(-0.00)) 1
,(DECFLOAT(1234), +infinity) -1
,(+infinity, +infinity) 0
,(+infinity, -infinity) 1
,(DECFLOAT(1234), -NaN) 1
)
SELECT TOTALORDER(d1,d2)
FROM temp1;
Figure 482, TOTALORDER function example
ANS. NOTES
==== =================
SELECT 'abcd' ==> abcd No change
ANSWER
======
SELECT c1 ==> ABCD
,REPLACE(c1,'AB','XY') ==> XYCD
,REPLACE(c1,'BA','XY') ==> ABCD
,TRANSLATE(c1,'XY','AB') XYCD
,TRANSLATE(c1,'XY','BA') YXCD
FROM scalar
WHERE c1 = 'ABCD';
Figure 485, REPLACE vs. TRANSLATE
ANSWER
===============================================
D1 POS2 POS1 ZERO NEG1 NEG2
------- ------- ------- ------- ------- -------
WITH temp1(d1) AS 123.400 123.400 123.400 123.000 120.000 100.000
(VALUES (123.400) 23.450 23.440 23.400 23.000 20.000 0.000
,( 23.450) 3.456 3.450 3.400 3.000 0.000 0.000
,( 3.456) 0.056 0.050 0.000 0.000 0.000 0.000
,( .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 486, TRUNCATE function examples
SELECT c1 ANSWER
,LENGTH(c1) AS l1 ========================
,VARCHAR(c1) AS v2 C1 L1 V2 L2 V3
,LENGTH(VARCHAR(c1)) AS l2 ------ -- ------ -- ----
,VARCHAR(c1,4) AS v3 ABCDEF 6 ABCDEF 6 ABCD
FROM scalar; ABCD 6 ABCD 6 ABCD
AB 6 AB 6 AB
Figure 488, VARCHAR function examples
WITH ANSWER
temp1 (n) AS ==========================
(VALUES (0) DTE DY WK DY WI DI
UNION ALL ---------- --- -- -- -- --
SELECT id ANSWER
,salary =============================
,"+"(salary) AS s2 ID SALARY S2 S3
,"+"(salary,id) AS s3 -- -------- -------- --------
FROM staff 10 98357.50 98357.50 98367.50
WHERE id < 40 20 78171.25 78171.25 78191.25
ORDER BY id; 30 77506.75 77506.75 77536.75
Figure 493, PLUS function examples
SELECT empno
,CHAR(birthdate,ISO) AS bdate1
,CHAR(birthdate + 1 YEAR,ISO) AS bdate2
SELECT id ANSWER
,salary ==============================
,"-"(salary) AS s2 ID SALARY S2 S3
,"-"(salary,id) AS s3 -- -------- --------- --------
FROM staff 10 98357.50 -98357.50 98347.50
WHERE id < 40 20 78171.25 -78171.25 78151.25
ORDER BY id; 30 77506.75 -77506.75 77476.75
Figure 495, MINUS function examples
SELECT id ANSWER
,salary =================================
,salary * id AS s2 ID SALARY S2 S3
,"*"(salary,id) AS s3 -- -------- ---------- ----------
FROM staff 10 98357.50 983575.00 983575.00
WHERE id < 40 20 78171.25 1563425.00 1563425.00
ORDER BY id; 30 77506.75 2325202.50 2325202.50
Figure 496, MULTIPLY function examples
SELECT id ANSWER
,salary ===========================
,salary / id AS s2 ID SALARY S2 S3
,"/"(salary,id) AS s3 -- -------- ------- -------
FROM staff 10 98357.50 9835.75 9835.75
WHERE id < 40 20 78171.25 3908.56 3908.56
ORDER BY id; 30 77506.75 2583.55 2583.55
Figure 497, DIVIDE function examples
SELECT id ANSWER
SELECT id AS ID ANSWER
,DIGITS(id) AS I2 ==============
,digi_int(id) AS I3 ID I2 I3
FROM staff -- ----- -----
WHERE id < 40 10 00010 00010
ORDER BY id; 20 00020 00020
30 00030 00030
Figure 501, Using sourced function - works
SELECT id ANSWER
,digi_int(INT(id)) =======
FROM staff
WHERE id < 50;
Figure 502, Using sourced function - fails
SELECT id ANSWER
,balance * 10 =======
FROM customers
ORDER BY id;
Figure 504, Do multiply - fails
SELECT id ANSWER
,balance * 10 AS newbal ==========
FROM customers ID NEWBAL
ORDER BY id; -- -------
1 1111.10
2 2222.20
Figure 506, Do multiply - works
SELECT id ANSWER
,"*"(balance,10) AS newbal ==========
FROM customers ID NEWBAL
ORDER BY id; -- -------
1 1111.10
2 2222.20
Figure 507, Do multiply - works
SELECT id AS id ANSWER
,calc(SMALLINT(id)) AS c1 ==========
,calc(INTEGER (id)) AS C2 ID C1 C2
FROM staff -- --- ---
WHERE id < 30 10 100 50
ORDER BY id; 20 200 100
UPDATE staff
SET name = remove_e(name)
WHERE id < 40;
SELECT empno
,hiredate
FROM employee
WHERE YEAR(hiredate) = YEAR(CURRENT DATE) - 1;
SELECT empno
,hiredate
FROM employee
WHERE YEAR_MONTH(hiredate) = YEAR_MONTH(CURRENT DATE) - 1;
Figure 527, 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 530, Use week-number functions
ANSWERS
SELECT * =======
FROM TABLE(NumList(-1)) AS xxx; 0
SELECT *
FROM TABLE(NumList(+0)) AS xxx; 0
SELECT *
FROM TABLE(NumList(+3)) AS xxx; 0
1
2
3
SELECT *
FROM TABLE(NumList(CAST(NULL AS INTEGER))) AS xxx; 0
Figure 532, Using num-list function
SELECT actno
,#days
,num ACTNO #DAYS NUM NEW_DATE
,emstdate + num DAYS AS new_date ----- ----- --- ----------
FROM (SELECT actno 70 16 0 2002-06-15
,emstdate 70 16 1 2002-06-16
,emendate 70 16 2 2002-06-17
,DAYS(emendate) - 70 16 3 2002-06-18
DAYS(emstdate) AS #days 70 16 4 2002-06-19
FROM emp_act act 70 16 5 2002-06-20
WHERE empno = '000260' 70 16 6 2002-06-21
AND projno = 'AD3113' 70 16 7 2002-06-22
AND actno < 100 70 16 8 2002-06-23
AND emptime = 0.5 70 16 9 2002-06-24
)AS aaa 70 16 10 2002-06-25
LEFT OUTER JOIN etc...
TABLE(NumList(#days)) AS ttt
ON 1 = 1
ORDER BY actno
,num;
Figure 535, Generate one row per date between start & end dates (2 of 2)
SELECT * ANSWER
FROM (SELECT * =========
FROM (SELECT * COL1 COL2
FROM seq_data ---- ----
ORDER BY col2 Ab 12
)AS xxx ab xy
ORDER BY ORDER OF xxx AB xy
,SUBSTR(col1,2) AB XY
)AS yyy ac XY
ORDER BY ORDER OF yyy
,col1;
Figure 550, Multiple nested ORDER BY statements
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))
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 568, 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 569, 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
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 A A00 - 128500 3 0 0 1
,GROUPING(sex) AS fs A - F 52750 1 0 1 0
FROM employee_view A - M 75750 2 0 1 0
GROUP BY CUBE(d1, dept, sex) A - - 128500 3 0 1 1
ORDER BY d1 B B01 M 41250 1 0 0 0
,dept B B01 - 41250 1 0 0 1
,sex; 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
- A00 F 52750 1 1 0 0
- A00 M 75750 2 1 0 0
- A00 - 128500 3 1 0 1
- B01 M 41250 1 1 0 0
- B01 - 41250 1 1 0 1
- C01 F 90470 3 1 0 0
- C01 - 90470 3 1 0 1
- D11 F 73430 3 1 0 0
- D11 M 148670 6 1 0 0
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 595, CUBE expressed using multiple GROUPING SETS
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 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 CUBE((d1, dept, sex)) D D11 M 148670 6 0 0 0
ORDER BY d1 - - - 482320 16 1 1 1
,dept
,sex;
Figure 596, CUBE on compound fields
SELECT d1 AS d1 ANSWER
,dept AS dpt ==================
,sex AS sx D1 DPT SX SAL R
,INT(SUM(salary)) AS sal -- --- -- ------ -
,SMALLINT(COUNT(*)) AS r A A00 F 52750 1
FROM employee_VIEW A A00 M 75750 2
GROUP BY d1 B B01 M 41250 1
,dept C C01 F 90470 3
,sex D D11 F 73430 3
ORDER BY 1,2,3; D D11 M 148670 6
Figure 598, Basic GROUP BY example
SELECT *
FROM (SELECT d1 AS d1
,dept AS dpt
,sex AS sx
,INT(SUM(salary)) AS 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
SELECT d1 ANSWER
,dept =====================
,sex D1 DEPT SEX SAL #R
,INT(SUM(salary)) AS sal -- ---- --- ------ --
,SMALLINT(COUNT(*)) AS #r A A00 F 52750 1
FROM employee_view A A00 M 75750 2
GROUP BY ROLLUP(d1,dept) A A00 - 128500 3
,ROLLUP(sex) A - F 52750 1
ORDER BY 1,2,3; A - M 75750 2
A - - 128500 3
B B01 M 41250 1
B B01 - 41250 1
B - M 41250 1
B - - 41250 1
C C01 F 90470 3
C C01 - 90470 3
C - F 90470 3
C - - 90470 3
FROM clause
JOIN ON clause
WHERE clause
GROUP BY and aggregate
HAVING clause
SELECT list
ORDER BY clause
FETCH FIRST
Figure 614, Query Processing Sequence
SELECT * ANSWER
FROM staff_v1 v1 ====================
LEFT OUTER JOIN ID NAME ID JOB
staff_v2 v2 -- -------- -- -----
ON 1 = 1 10 Sanders - -
AND v1.id = v2.id 20 Pernal 20 Sales
ORDER BY v1.id 30 Marenghi 30 Clerk
,v2.job; 30 Marenghi 30 Mgr
Figure 615, Sample Views used in Join Examples
SELECT * ANSWER
FROM staff_v1 v1 ====================
LEFT OUTER JOIN ID NAME ID JOB
staff_v2 v2 -- -------- -- -----
ON 1 = 1 20 Pernal 20 Sales
WHERE v1.id = v2.id 30 Marenghi 30 Clerk
ORDER BY v1.id 30 Marenghi 30 Mgr
,v2.job;
Figure 616, Sample Views used in Join Examples
SELECT * ANSWER
FROM staff_v1 v1 ====================
,staff_v2 v2 ID NAME ID JOB
WHERE v1.id = v2.id -- -------- -- -----
ORDER BY v1.id 20 Pernal 20 Sales
,v2.job; 30 Marenghi 30 Clerk
30 Marenghi 30 Mgr
Figure 618, Inner Join SQL (1 of 2)
SELECT * ANSWER
FROM staff_v1 v1 ====================
INNER JOIN ID NAME ID JOB
staff_v2 v2 -- -------- -- -----
ON v1.id = v2.id 20 Pernal 20 Sales
ORDER BY v1.id 30 Marenghi 30 Clerk
,v2.job; 30 Marenghi 30 Mgr
Figure 619, Inner Join SQL (2 of 2)
SELECT * ANSWER
FROM staff_v1 v1 ====================
INNER JOIN ID NAME ID JOB
staff_v2 v2 -- -------- -- -----
ON v1.id = v2.id 20 Pernal 20 Sales
AND v2.job <> 'Mgr' 30 Marenghi 30 Clerk
ORDER BY v1.id
,v2.job;
Figure 620, Inner join, using ON check
SELECT * ANSWER
FROM staff_v1 v1 ====================
INNER 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 621, Inner join, using WHERE check
SELECT *
FROM staff_v1 v1
LEFT OUTER JOIN
staff_v2 v2
ON v1.id = v2.id
ORDER BY 1,4;
Figure 623, Left Outer Join SQL (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 - -
AND v2.job <> 'Mgr' 20 Pernal 20 Sales
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 626, 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 627, WHERE check on table being joined to (2 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 - -
AND v1.name > 'N' 20 Pernal 20 Sales
ORDER BY v1.id 30 Marenghi - -
,v2.job;
Figure 628, ON check on table being joined from
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
SELECT * ANSWER
FROM staff_v1 v1 ====================
RIGHT OUTER JOIN ID NAME ID JOB
staff_v2 v2 -- -------- -- -----
ON v1.id = v2.id 20 Pernal 20 Sales
ORDER BY v2.id 30 Marenghi 30 Clerk
,v2.job; 30 Marenghi 30 Mgr
- - 40 Sales
- - 50 Mgr
Figure 631, Right Outer Join SQL (1 of 2)
SELECT * ANSWER
FROM staff_v1 v1 ====================
FULL OUTER JOIN ID NAME ID JOB
staff_v2 v2 -- -------- -- -----
ON v1.id = v2.id 10 Sanders - -
ORDER BY v1.id 20 Pernal 20 Sales
,v2.id 30 Marenghi 30 Clerk
,v2.job; 30 Marenghi 30 Mgr
- - 40 Sales
- - 50 Mgr
Figure 634, Full Outer Join SQL
SELECT * ANSWER
FROM staff_v1 v1 ====================
FULL OUTER JOIN ID NAME ID JOB
staff_v2 v2 -- -------- -- -----
ON v1.id = v2.id 10 Sanders - -
AND v1.id > 20 20 Pernal - -
ORDER BY v1.id 30 Marenghi 30 Clerk
,v2.id 30 Marenghi 30 Mgr
,v2.job; - - 20 Sales
- - 40 Sales
- - 50 Mgr
Figure 637, Full Outer Join, match on keys > 20
SELECT * ANSWER
FROM staff_v1 v1 ====================
FULL OUTER JOIN ID NAME ID JOB
staff_v2 v2 -- -------- -- -----
ON v1.id = v2.id 10 Sanders - -
AND +1 = -1 20 Pernal - -
ORDER BY v1.id 30 Marenghi - -
,v2.id - - 20 Sales
,v2.job; - - 30 Clerk
- - 30 Mgr
- - 40 Sales
- - 50 Mgr
Figure 638, Full Outer Join, match on keys (no rows match)
SELECT * ANSWER
FROM staff_v1 v1 ====================
FULL OUTER JOIN ID NAME ID JOB
staff_v2 v2 -- -------- -- -----
SELECT * ANSWER
FROM staff_v1 v1 ====================
FULL OUTER JOIN ID NAME ID JOB
staff_v2 v2 -- -------- -- -----
ON +1 <> -1 10 Sanders 20 Sales
ORDER BY v1.id 10 Sanders 30 Clerk
,v2.id 10 Sanders 30 Mgr
,v2.job; 10 Sanders 40 Sales
10 Sanders 50 Mgr
20 Pernal 20 Sales
STAFF_V1 STAFF_V2 20 Pernal 30 Clerk
+-----------+ +---------+ 20 Pernal 30 Mgr
|ID|NAME | |ID|JOB | 20 Pernal 40 Sales
|--|--------| |--|------| 20 Pernal 50 Mgr
|10|Sanders | |20|Sales | 30 Marenghi 20 Sales
|20|Pernal | |30|Clerk | 30 Marenghi 30 Clerk
|30|Marenghi| |30|Mgr | 30 Marenghi 30 Mgr
+-----------+ |40|Sales | 30 Marenghi 40 Sales
|50|Mgr | 30 Marenghi 50 Mgr
+---------+
Figure 640, Full Outer Join, don't match on keys (all rows match)
SELECT * ANSWER
FROM staff_v1 v1 ====================
FULL JOIN ID NAME ID JOB
staff_v2 v2 -- -------- -- -----
ON v1.id = v2.id 20 Pernal 20 Sales
WHERE v1.id = v2.id 30 Marenghi 30 Clerk
ORDER BY 1,3,4; 30 Marenghi 30 Mgr
Figure 641, Full Outer Join, turned into an inner join by WHERE
STAFF_V1 STAFF_V2
+-----------+ +---------+ ANSWER
|ID|NAME | |ID|JOB | OUTER-JOIN CRITERIA ============
|--|--------| |--|------| ==================> ???, 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 643, Outer join V1.ID < 30, check applied in WHERE (after join)
SELECT * ANSWER
FROM staff_v1 v1 ====================
FULL JOIN ID NAME ID JOB
staff_v2 v2 -- -------- -- -----
ON v1.id = v2.id 10 Sanders - -
AND v1.id < 30 20 Pernal 20 Sales
ORDER BY 1,3,4; 30 Marenghi - -
- - 30 Clerk
- - 30 Mgr
- - 40 Sales
- - 50 Mgr
Figure 644, Outer join V1.ID < 30, check applied in ON (during join)
SELECT * ANSWER
FROM (SELECT * ====================
FROM staff_v1 ID NAME ID JOB
WHERE id < 30) AS v1 -- -------- -- -----
FULL OUTER JOIN 10 Sanders - -
staff_v2 v2 20 Pernal 20 Sales
ON v1.id = v2.id - - 30 Clerk
ORDER BY 1,3,4; - - 30 Mgr
- - 40 Sales
- - 50 Mgr
Figure 645, Outer join V1.ID < 30, check applied in WHERE (before join)
SELECT * ANSWER
FROM staff_v1 v1 ====================
FULL OUTER JOIN ID NAME ID JOB
staff_v2 v2 -- -------- -- -----
ON v1.id = v2.id 10 Sanders - -
WHERE v1.id < 30 20 Pernal 20 Sales
OR v1.id = v2.id 30 Marenghi 30 Clerk
OR v1.id IS NULL 30 Marenghi 30 Mgr
ORDER BY 1,3,4; - - 40 Sales
- - 50 Mgr
Figure 647, Outer join V1.ID < 30, (gives wrong answer - see text)
SELECT *
SELECT *
FROM staff_v1 v1
INNER JOIN
staff_v2 v2
ON 'A' <> 'B'
ORDER BY v1.id
,v2.id
,v2.job;
Figure 650, Cartesian Product SQL (2 of 2)
SELECT *
FROM (SELECT v1.* ,'V1' AS flag FROM staff_v1 v1) AS v1
FULL OUTER JOIN
(SELECT v2.* ,'V2' AS flag FROM staff_v2 v2) AS v2
ON v1.id = v2.id
WHERE v1.flag IS NULL ANSWER
OR v2.flag IS NULL =============================
ORDER BY v1.id ID NAME FLAG ID JOB FLAG
,v2.id -- ------- ---- -- ----- ----
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 657, Outer Join SQL, getting only non-matching rows
SELECT * ANSWER
FROM table1 =======
WHERE t1a = T1A T1B
(SELECT t2a --- --
FROM table2 A AA
WHERE t2a = 'A');
SELECT * ANSWER
FROM table1 =======
WHERE t1a =
SELECT * ANSWER
FROM table1 ======
WHERE t1a = ALL 0 rows
(SELECT t2b
FROM table2 SQ-#1 SQ-#2TABLE1 TABLE2
WHERE t2b >= 'X') RESLT RESLT+-------+ +-----------+
AND 0 <> +---+ +---+|T1A|T1B| |T2A|T2B|T2C|
(SELECT COUNT(*) |T2B| |(*)||---|---| |---|---|---|
FROM table2 |---| |---||A |AA | |A |A |A |
WHERE t2b >= 'X'); +---+ |0 | |B |BB | |B |A | - |
+---+|C |CC | +-----------+
+-------+ "-" = null
Figure 687, ALL sub-query, with extra check for empty set
SELECT * ANSWER
FROM table1 ======
WHERE EXISTS 0 rows
(SELECT *
FROM table2
WHERE t2b >= 'X');
Figure 689, EXISTS sub-query, always returns a non-match
SELECT *
FROM table1
WHERE t1a = ALL
(SELECT t2c
FROM table2
WHERE t2c >= 'A');
Figure 691, NOT EXISTS vs. ALL, ignore nulls, find match
SELECT *
FROM table1
WHERE t1a = ALL
(SELECT t2c
FROM table2
WHERE t2c >= 'X');
Figure 692, NOT EXISTS vs. ALL, ignore nulls, no match
SELECT *
FROM table1
WHERE t1a = SOME
(SELECT t2c
FROM table2);
SELECT *
FROM table1
WHERE t1a IN
(SELECT t2c
FROM table2);
Figure 711, Sub-queries, true if any match
SELECT t1.*
FROM table1 t1 ANSWER
,(SELECT DISTINCT t2c =======
FROM table2 T1A T1B
)AS t2 --- ---
WHERE t1.t1a = t2.t2c; A AA
SELECT t1.*
FROM table1 t1
INNER JOIN
(SELECT DISTINCT t2c
FROM table2
)AS t2
ON t1.t1a = t2.t2c;
Figure 712, Joins, true if any match
SELECT *
FROM table1
WHERE t1a IN
(SELECT t2b
FROM table2
GROUP BY t2b
HAVING COUNT(*) = 10);
Figure 713, Sub-queries, true if ten match (1 of 2)
SELECT * ANSWER
FROM table1 ======
WHERE (t1a,10) IN 0 rows
(SELECT t2b, COUNT(*)
FROM table2
GROUP BY t2b);
Figure 714, Sub-queries, true if ten match (2 of 2)
ANSWER
SELECT t1.* ======
FROM table1 t1 0 rows
,(SELECT t2b
FROM table2
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 715, Joins, true if ten match
SELECT * ANSWER
FROM table1 =======
WHERE t1a = ALL T1A T1B
(SELECT t2b --- ---
FROM table2 A AA
WHERE t2b >= 'X'); B BB
C CC
SELECT *
FROM table1
WHERE NOT EXISTS
(SELECT *
FROM table2
WHERE t1a <> t2b
AND t2b >= 'X');
Figure 717, Sub-queries, true if all match, empty set
R1 R1 R1 R1 R1 R1 R1
UNION UNION INTERSECT INTERSECT EXCEPT EXCEPT MINUS
R2 ALL R2 ALL R2 ALL R2
R1 R2 R2 R2 R2
-- -- ----- ----- --------- ----- ------ ------ -----
A A A A A A E A E
A A B A B A C
A B C A C B C
B B D A B E
B B E A C
C C B
C D B
C B
E B
B
C
C
C
C
D
E
Figure 719, Examples of Union, Except, and Intersect
SELECT R1 R1 R1
FROM R1 EXCEPT EXCEPT ALL
EXCEPT R1 R2 R2 R2
SELECT R2 -- -- ===== ==========
FROM R2 A A E A
ORDER BY 1; A A C
A B C
SELECT R1 B B E
FROM R1 B B
EXCEPT ALL C C
SELECT R2 C D
FROM R2 C
ORDER BY 1; E
Figure 724, Except and Except All SQL (R1 on top)
SELECT R2 R2 R2
FROM R2 EXCEPT EXCEPT ALL
EXCEPT R1 R2 R1 R1
SELECT R1 -- -- ===== ==========
FROM R1 A A D B
ORDER BY 1; A A D
A B
SELECT R2 B B
FROM R2 B B
EXCEPT ALL C C
SELECT R1 C D
FROM R1 C
ORDER BY 1; E
Figure 725, Except and Except All SQL (R2 on top)
UPDATE sales_data
SET amount = amount / 2
WHERE sales_rep = 'JOHN';
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 747, 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 748, Query that uses materialized query table (2 of 3)
SELECT #emps
,DEC(SUM(sum_sal),9,2) AS sal_sal
,SMALLINT(COUNT(*)) AS #depts
FROM (SELECT emp.workdept
,DEC(SUM(emp.salary),8,2) AS sum_sal
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 755, 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 756, Query that doesn't use materialized query table (2 of 2)
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 759, Query that uses materialized query table
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 762, Query that uses 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 765, 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
SELECT cust#
,cname
FROM FINAL TABLE CUST# CNAME
(INSERT INTO intl_customer (cname, frst_sale, #sales) ----- -----
VALUES ('SUE','2002-11-12',2) 3 SUE
,('DEB','2002-11-13',2)); 4 DEB
Figure 796, Insert into tables with common sequence
SELECT id
,salary
FROM (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 809, Nested Table Expression
SELECT id ANSWER
,dept ==========================
,salary ID DEPT SALARY MAX_SAL
,max_sal --- ---- -------- --------
FROM staff 10 20 18357.50 18357.50
LEFT OUTER JOIN 190 20 14252.75 18357.50
(SELECT dept AS dept# 200 42 11508.60 18352.80
,MAX(salary) AS max_sal 220 51 17654.50 -
FROM staff
WHERE dept < 50
GROUP BY dept
)AS STAFF_dept
ON dept = dept#
WHERE name LIKE 'S%'
ORDER BY id;
Figure 814, Identical query (2 of 3) - using fullselect in FROM
SELECT id ANSWER
,dept ==========================
,salary ID DEPT SALARY MAX_SAL
,(SELECT MAX(salary) --- ---- -------- --------
FROM staff s2 10 20 18357.50 18357.50
WHERE s1.dept = s2.dept 190 20 14252.75 18357.50
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 815, Identical query (3 of 3) - using fullselect in SELECT
WITH ANSWER
temp1 AS ==========
(SELECT dept MAX_AVG
,AVG(salary) AS avg_sal ----------
FROM staff 20865.8625
GROUP BY dept),
temp2 AS
(SELECT MAX(avg_sal) AS max_avg
FROM temp1)
SELECT *
FROM temp2;
Figure 819, Query with two common table expressions
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
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 824, Nested column function usage
SELECT id ANSWER
FROM (SELECT * ======
FROM (SELECT id, years, salary ID
FROM (SELECT * ---
FROM (SELECT * 170
FROM staff 180
WHERE dept < 77 230
)AS t1
WHERE id < 300
)AS t2
WHERE job LIKE 'C%'
)AS t3
WHERE salary < 18000
)AS t4
WHERE years < 5;
Figure 825, Nested fullselects
SELECT id ANSWER
,salary ====================
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 78171.25 18357.50
FROM staff a 30 77506.75 18006.00
WHERE id < 60 40 18006.00 18006.00
ORDER BY id; 50 20659.80 20659.80
Figure 830, 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 78171.25 18357.50 22959.20
,(SELECT MAX(salary) 30 38 77506.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 831, Use correlated and uncorrelated Full-Selects in a SELECT
list
UPDATE staff a
SET (salary,years) =
(SELECT AVG(salary) + 2000
,MAX(years)
FROM staff b
WHERE a.dept = b.dept )
WHERE id < 60;
Figure 835, Update two fields by referencing Full-Select
COMMIT;
ANSWER
SELECT COUNT(*) ======
FROM session.fred; 0
Figure 840, Temporary table with index
HIERARCHY AAA
+---------------+ |
|PKEY |CKEY |NUM| +-----+-----+
|-----|-----|---| | | |
|AAA |BBB | 1| BBB CCC DDD
|AAA |CCC | 5| | |
|AAA |DDD | 20| +-+ +-+--+
|CCC |EEE | 33| | | |
|DDD |EEE | 44| EEE FFF
|DDD |FFF | 5| |
OBJECTS_RELATES AAA
+---------------------+ |
|KEYO |PKEY |NUM|PRICE| +-----+-----+
|-----|-----|---|-----| | | |
|AAA | | | $10| BBB CCC DDD
|BBB |AAA | 1| $21| |
|CCC |AAA | 5| $23| +--+--+
|DDD |AAA | 20| $25| | |
|EEE |DDD | 44| $33| EEE FFF
|FFF |DDD | 5| $34| |
|GGG |FFF | 5| $44| |
+---------------------+ GGG
Figure 859, Divergent Hierarchy - Table and Layout
HIERARCHY#1 EXPLODED#1
AAA +--------------------+ +-------------+
| |KEYY|PKEY|DATA | |PKEY|CKEY|LVL|
BBB |----|----|----------| |----|----|---|
| |AAA |AAA |SOME DATA | |AAA |AAA | 0|
+-----+ |BBB |AAA |MORE DATA | |AAA |BBB | 1|
| | |CCC |BBB |MORE JUNK | |AAA |CCC | 2|
CCC EEE |DDD |CCC |MORE JUNK | |AAA |DDD | 3|
| |EEE |BBB |JUNK DATA | |AAA |EEE | 2|
DDD +--------------------+ |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 876, Data Hierarchy, with normalized and exploded representations
SELECT *
FROM exploded#2
WHERE pkey = :host-var
ORDER BY pkey
UPDATE cust_balance
SET balance = balance + 123
WHERE cust# <= 2;
UPDATE cust_balance
SET balance = balance * -1
WHERE cust# = -1;
UPDATE cust_balance
SET balance = balance - 123
WHERE cust# = 1;
SELECT *
FROM us_sales
WHERE sale_update_ts <= CURRENT TIMESTAMP;
Figure 909, Select run after multi-row insert
UPDATE us_sales
SET sale_value = DECIMAL(sale_value) + 1
WHERE invoice# = 5
AND ROW CHANGE TIMESTAMP for us_sales = '2007-11-10-01.02.03';
Figure 911, Update that checks for intervening updates
SELECT empno
,lastname
,workdept
,salary
FROM employee
WHERE empno = '000250';
Figure 941, Sample query
SELECT all-columns
FROM all-relevant-tables
WHERE all-predicates-are-true
Figure 942, Sample pseudo-query
SELECT COUNT(*)
FROM all-relevant-tables
WHERE empno = '000250';
Figure 943, Sample pseudo-query
SELECT all-columns
FROM all-relevant-tables
WHERE empno = '000250';
Figure 945, Sample pseudo-query
WITH temp1 AS
(SELECT tabname
,VARCHAR(
' SELECT *' ||
' FROM ' || tabschema || '.' || tabname ||
' WHERE ' || colname || ' = ''000250'''
) AS SQL_text
FROM syscat.columns
WHERE tabschema = USER
AND colname = 'EMPNO'
AND typename = 'CHARACTER'
)
SELECT CHAR(t1.tabname,10) AS tabname
,t2.row_number AS row#
,t2.col_num AS col#
,CHAR(t2.col_name,15) AS colname
,CHAR(t2.col_type,15) AS coltype
,CHAR(t2.col_value,20) AS colvalue
FROM temp1 t1
,TABLE(tab_transpose(sql_text)) AS t2
ORDER BY t1.tabname
,t2.row_number
,t2.col_num;
Figure 946, Select all matching columns/rows in all matching tables
ANSWER
==========================
DEPT EMPNO SALARY #ROWS
SELECT workdept AS dept ---- ------ -------- -----
,empno E11 000290 35340.00 7
,salary E21 200330 35370.00 6
,get_Integer( E21 200340 31840.00 6
' SELECT count(*)' ||
' FROM employee' ||
' where workdept = ''' || workdept || ''' ')
AS #rows
FROM employee
WHERE salary < 35500
ORDER BY workdept
,empno;
Figure 958, Java function usage example
import java.lang.*;
import COM.ibm.db2.app.*;
import java.sql.*;
import java.math.*;
import java.io.*;
WITH
make_queries AS
(SELECT tab.tabschema
,tab.tabname
,' SELECT EMPNO ' ||
' FROM ' || tab.tabschema || '.' || tab.tabname
AS sql_text
FROM syscat.tables tab
,syscat.columns col
WHERE tab.tabschema = USER
AND tab.type = 'T'
AND col.tabschema = tab.tabschema
AND col.tabname = tab.tabname
AND col.colname = 'EMPNO'
AND col.typename = 'CHARACTER'
AND col.length = 6
),
run_queries AS
(SELECT qqq.*
,ttt.*
FROM make_queries qqq
,TABLE(tab_Varchar(sql_text)) AS ttt
)
SELECT CHAR(row_value,10) AS empno
,COUNT(*) AS #rows
,COUNT(DISTINCT tabschema || tabname) AS #tabs
,CHAR(MIN(tabname),18) AS min_tab
,CHAR(MAX(tabname),18) AS max_tab
FROM run_queries
GROUP BY row_value
HAVING COUNT(DISTINCT tabschema || tabname) > 3
ORDER BY row_value
SELECT *
FROM empprojact
WHERE empno = '000150';
ANSWER
=================================================
EMPNO PROJNO ACTNO EMPTIME EMSTDATE EMENDATE
------ ------ ----- ------- ---------- ----------
000150 MA2112 60 1.00 01/01/2002 07/15/2002
000150 MA2112 180 1.00 07/15/2002 02/01/2003
Figure 963, Select rows
WITH
make_queries AS
(SELECT tab.tabschema
,tab.tabname
,' SELECT *' ||
' FROM ' || tab.tabname ||
' WHERE empno = ''000150'''
AS sql_text
FROM syscat.tables tab
,syscat.columns col
WHERE tab.tabschema = USER
AND tab.type = 'T'
AND col.tabschema = tab.tabschema
AND col.tabname = tab.tabname
AND col.colname = 'EMPNO'
AND col.typename = 'CHARACTER'
AND col.length = 6
),
run_queries AS
(SELECT qqq.*
,ttt.*
FROM make_queries qqq
,TABLE(tab_Transpose(sql_text)) AS ttt
)
SELECT SUBSTR(tabname,1,11) AS tab_name
,SMALLINT(row_number) AS row#
,col_num AS col#
,CHAR(col_name,13) AS col_name
,CHAR(col_type,10) AS col_type
,col_length AS col_len
,SMALLINT(LENGTH(col_value)) AS val_len
,SUBSTR(col_value,1,20) AS col_value
FROM run_queries
ORDER BY 1,2,3;
Figure 965, Select rows in any table – then transpose
WITH
search_values (search_type,search_length,search_value) AS
(VALUES ('CHARACTER',6,'000150')
),
list_columns AS
(SELECT val.search_value
,tab.tabschema
make_queries (search_value
,tabschema
,tabname
,colname
,col_a
,col_d
,sql_text) AS
(SELECT tb1.*
,VARCHAR(' SELECT *' ||
' FROM ' || tabname ||
' WHERE ' || colname || ' = ''' ||
search_value || ''''
,4000)
FROM list_columns tb1
WHERE col_a = 1
UNION ALL
SELECT tb2.*
,mqy.sql_text ||
' OR ' || tb2.colname ||
' = ''' || tb2.search_value || ''''
FROM list_columns tb2
,make_queries mqy
WHERE tb2.search_value = mqy.search_value
AND tb2.tabschema = mqy.tabschema
AND tb2.tabname = mqy.tabname
AND tb2.col_a = mqy.col_a + 1
),
run_queries AS
(SELECT qqq.*
,ttt.*
FROM make_queries qqq
,TABLE(tab_Transpose_4K(sql_text)) AS ttt
WHERE col_d = 1
)
Figure 967, Select rows in any table – then transpose (part 1 of 2)
Connection con;
Statement stmt;
ResultSet rs;
ResultSetMetaData rsmtadta;
int rowNum;
int i;
int outLength;
short colNum;
int colCount;
String[] colName = new String[1100];
String[] colType = new String[1100];
int[] colSize = new int[1100];
public void writeRow()
throws Exception {
set(2, rowNum);
set(3, (short) colCount);
set(4, colNum);
set(5, colName[colNum]);
set(6, colType[colNum]);
Figure 972, CREATE FUNCTION java code (part 1 of 3)
set(7, colSize[colNum]);
if (colType[colNum].equals("XML") ||
colType[colNum].equals("BLOB") ||
colType[colNum].equals("CLOB") ||
colType[colNum].equals("DBLOB") ||
colType[colNum].equals("GRAPHIC") ||
colType[colNum].equals("VARGRAPHIC") ||
colSize[colNum] > outLength) {
// DON'T DISPLAY THIS VALUE
return;
}
else if (rs.getString(colNum) != null) {
// DISPLAY THIS COLUMN VALUE
set(8, rs.getString(colNum));
}
}
WITH temp1 AS
(SELECT tabschema
,tabname
FROM syscat.tables
WHERE tabschema = 'FRED'
AND type = 'S'
AND status = 'C'
AND tabname LIKE '%DEPT%'
)
SELECT CHAR(tab.tabname,20) AS tabname
WITH temp1 AS
(SELECT tabschema
,tabname
FROM syscat.tables
WHERE tabschema = USER
AND tabname LIKE 'S%'
)
WITH
temp0 AS
(SELECT RTRIM(tabschema) AS schema
,tabname AS old_tabname
,tabname || '_C2' AS new_tabname
FROM syscat.tables
WHERE tabschema = USER
AND tabname LIKE 'S%'
),
temp1 AS
(SELECT tab.*
,stm.sqlcode AS sqlcode1
,CHAR(stm.sqltext,200) AS sqltext1
FROM temp0 AS tab
,TABLE(execute_immediate(
' CREATE TABLE ' || schema || '.' || new_tabname ||
' LIKE ' || schema || '.' || old_tabname
))AS stm
),
temp2 AS
(SELECT tab.*
,stm.sqlcode AS sqlcode2
,CHAR(stm.sqltext,200) AS sqltext2
FROM temp1 AS tab
,TABLE(execute_immediate(
' INSERT INTO ' || schema || '.' || new_tabname ||
' SELECT * FROM ' || schema || '.' || old_tabname
))AS stm
)
SELECT CHAR(old_tabname,20) AS tabname
,sqlcode1 ANSWER
,sqlcode2 =========================
FROM temp2 TABNAME SQLCODE1 SQLCODE2
ORDER BY old_tabname ------- -------- --------
FROM clause
JOIN ON clause
WHERE clause
GROUP BY and aggregate
HAVING clause
SELECT list
ORDER BY clause
FETCH FIRST
Figure 981, Query Processing Sequence
SELECT *
FROM TABLE(NumList(100)) AS xxx;
Figure 983, Use user-defined-function to get list of 100 numbers
ANSWER
=======================
S# RAN1 RAN2 RAN3
WITH -- ------ ------ ------
temp1 (s1) AS 0 1251 365370 114753
(VALUES (0) 1 350291 280730 88106
UNION ALL 2 710501 149549 550422
SELECT s1 + 1 3 147312 33311 2339
FROM temp1 4 8911 556 73091
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 986, Create RAND data with different distributions
SELECT *
FROM staff TABLESAMPLE BERNOULLI(5) REPEATABLE(1234)
ORDER BY id;
Figure 999, 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 1000, Sample rows in two tables
SELECT *
FROM session.nyc_staff TABLESAMPLE SYSTEM(34.55)
WHERE id < 100
AND salary > 100
ORDER BY id;
Figure 1001, Sample Views used in Join Examples
SELECT 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 -0494.10 049410 -494 -494 00494
-12.00 -0012.00 001200 -12 -12 00012
508.60 0508.60 050860 508 508 00508
1009.75 1009.75 100975 1009 1009 01009
Figure 1007, CHAR and DIGITS function usage
SELECT d_sal
,char_right(d_sal) AS d_chr
FROM (SELECT DEC(salary - 11000,6,2) AS d_sal
FROM staff
WHERE salary > 10000 ANSWER
AND salary < 12200 ===============
)AS xxx D_SAL D_CHR
ORDER BY d_sal; ------- -------
-494.10 -494.10
-12.00 -12.00
508.60 508.60
1009.75 1009.75
Figure 1011, Convert DECIMAL to CHAR
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;
Figure 1013, Convert DECIMAL to CHAR with commas
WITH tab1(ts1) AS
(VALUES CAST('1998-11-22-03.44.55.123456' AS TIMESTAMP))
SELECT empno
,firstnme
,lastname
,job
FROM employee
WHERE empno < '000100'
ORDER BY empno;
Figure 1015, 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 1016, Sample query with column control
SELECT id
,salary
,INT(salary / 1500) AS len
,REPEAT('*',INT(salary / 1500)) AS salary_chart
FROM staff
WHERE id > 120 ANSWER
AND id < 190 ===================================
ORDER BY id; ID SALARY LEN SALARY_CHART
--- -------- --- ---------------
130 10505.90 7 *******
140 21150.00 14 **************
ANSWER
===================================
ID SALARY SALARY_CHART
WITH --- -------- --------------------
temp1 (id, salary) AS 130 10505.90 *********
(SELECT id 140 21150.00 ******************
,salary 150 19456.50 ****************
FROM staff 160 22959.20 ********************
WHERE id > 120 170 12258.50 **********
AND id < 190), 180 12009.75 **********
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 1018, Make chart of fixed length
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)
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
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, 78171.25
15 Mgr 20659.80 38, 24964.50, 77506.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 78171.25
38 Clerk 24964.50
38 Mgr 77506.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 1037, Contents of first temporary table and final output
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 78171.25 52.1718
30 77506.75 57.6057
Figure 1039, Reversing numeric field
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 1046, Query that uses pause function
--#SET DELIMITER !
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 1050, 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%')
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 1052, 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.*
WITH ANSWER
temp1 (num) AS ============================
(VALUES (INTEGER(0)) NUM HEX H2I
UNION ALL --------- -------- ---------
SELECT (num + 1) * 7 -87432800 A0E1C9FA -87432800
FROM temp1 -12490387 6D6941FF -12490387
WHERE num < 1E6), -1784328 F8C5E4FF -1784328
temp2 (sgn) AS -254891 551CFCFF -254891
(VALUES (+1) -36400 D071FFFF -36400
,(-13)), -5187 BDEBFFFF -5187
temp3 (num) AS -728 28FDFFFF -728
(SELECT DISTINCT -91 A5FFFFFF -91
num * sgn 0 00000000 0
FROM temp1 7 07000000 7
,temp2) 56 38000000 56
SELECT num 399 8F010000 399
,HEX(num) AS hex 2800 F00A0000 2800
,hex_to_int(HEX(num)) AS h2i 19607 974C0000 19607
FROM temp3 137256 28180200 137256
ORDER BY num; 960799 1FA90E00 960799
6725600 E09F6600 6725600
Figure 1056, Using trigger to convert data
SELECT *
FROM supermarket_sales
WHERE DATE(sales_ts) = '2003-08-01'
ORDER BY sales_ts;
Figure 1061, Select rows for given date
SELECT *
FROM supermarket_sales
WHERE sales_ts BETWEEN '2003-08-01-00.00.00'
AND '2003-08-01-24.00.00'
ORDER BY sales_ts;
SELECT id ANSWER
,name ===========
FROM staff ID NAME
WHERE id <= 100 -- --------
AND id = (INT(RAND()* 10) * 10) + 10 30 Marenghi
ORDER BY id; 60 Quigley
Figure 1075, Get random rows - Incorrect
WITH ANSWER
SELECT id ANSWER
,name ==========
FROM (SELECT s2.* ID NAME
,ROW_NUMBER() OVER(ORDER BY r1) AS r2 -- -------
FROM (SELECT s1.* 10 Sanders
,RAND() AS r1 40 O'Brien
FROM staff s1 60 Quigley
WHERE id <= 100
)AS s2
)as s3
WHERE r2 <= 3
ORDER BY id;
Figure 1078, Get random rows - Distinct
ANSWER
======
BGN_TSTAMP ELP_SEC END_TSTAMP
-------------------------- ------- --------------------------
2001-01-15-01.02.03.000000 1.234 2001-01-15-01.02.04.000000
2001-01-15-01.02.03.123456 1.234 2001-01-15-01.02.04.123456
Figure 1079, Date/Time manipulation - wrong
ANSWER
======
BGN_TSTAMP ELP_SEC END_TSTAMP
-------------------------- ------- --------------------------
2001-01-15-01.02.03.000000 1.234 2001-01-15-01.02.04.234000
2001-01-15-01.02.03.123456 1.234 2001-01-15-01.02.04.357456
Figure 1080, Date/Time manipulation - right
EXEC-SQL
DECLARE fred CURSOR FOR
SELECT *
FROM staff
WHERE id < 1000
ORDER BY id;
END-EXEC;
EXEC-SQL
OPEN fred
END-EXEC;
EXEC-SQL
FETCH fred
INTO :HOST-VARS
END-EXEC;
END-DO;
EXEC-SQL
CLOSE fred
END-EXEC;
Figure 1092, Ambiguous Cursor
WITH
temp1 (dec1, dbl1) AS
(VALUES (DECIMAL(1),DOUBLE(1)))
,temp2 (dec1, dec2, dbl1, dbl2) AS
(SELECT dec1
,dec1 / 3 AS dec2
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 1111, Comparing float and decimal multiplication, answer