Presentation is loading. Please wait.

Presentation is loading. Please wait.

MODULE 1 1 Please logon to

Similar presentations


Presentation on theme: "MODULE 1 1 Please logon to"— Presentation transcript:

1 MODULE 1 1 Please logon to www.tableaujob.weebly.com Mail @ callmenaresh@mail.com

2 Obtain the employee numbers for all the employees in the Employee table of the Customer Service Database. A Simple SQL SELECT 2

3 3

4 SELECT All Columns and All Rows Obtain all columns of information for all the employees in Employee table of the Customer Service Database. 4

5 5

6 WHERE Clause The WHERE clause is used to qualify the rows returned by a SELECT statement. 6

7 ORDER BY Clause The ORDER BY clause specifies the column(s) to be used for sorting the result. Alternatives to above example: ORDER BY hire_date ASC; (ascending sort) ORDER BY 4;(numeric designator) ORDER BY hire_date DESC; (descending sort) 7

8 Multiple ORDER BY Columns First column specified is major sort column. Second and subsequent columns are minor sort columns. 8

9 DISTINCT Option Without DISTINCT option: 9

10 With DISTINCT option: 10

11 Recommended Coding Conventions Course materials use Teradata Extensions for object names in order to improve readability: · Lower and mixed case · Up to 30 characters 11

12 Changing the Default Database Once logged on, you change the default database by using the DATABASE command. Example: The default database is “payroll” until: · User logs off · A new Database command is issued You can override a default DATABASE in a single SQL statement by specifying the database you wish to query: Example: 12

13 Module 3 13

14 HELP DATABASE 14

15 HELP TABLE To list the columns for a specific table, use the HELP TABLE statement. Differences: V2R2.0 vs. Previous Release(s) 15

16 HELP TABLE 16

17 Continuation HELP TABLE 17

18 HELP Commands: Session Characteristics 18

19 HELP commands: SQL and RDBMS utility syntax 19

20 SHOW TABLE Command Results CREATE SET TABLE CUSTOMER_SERVICE.employee,FALLBACK, NO BEFORE JOURNAL, NO AFTER JOURNAL ( employee_number INTEGER, manager_employee_number INTEGER, department_number INTEGER, job_code INTEGER, last_name CHAR(20) NOT CASESPECIFIC NOT NULL, first_name VARCHAR(30) NOT CASESPECIFIC NOT NULL, hire_date DATE NOT NULL, birthdate DATE NOT NULL, salary_amount DECIMAL(10,2) NOT NULL) UNIQUE PRIMARY INDEX ( employee_number ); 20

21 SHOW VIEW Command Results CREATE VIEW dept AS SELECT department_number,department_name,budget_amount,manager_employee_number FROM customer_service.department WHERE department_number > 401; 21

22 SHOW MACRO Command Results CREATE MACRO get_depts AS (SELECT department_number,department_name,budget_amount,manager_employee_number FROM dept; ); 22

23 EXPLAIN Explanation 1) First, we lock a distinct CUSTOMER_SERVICE.”pseudo table” for read on a Row Hash to prevent global deadlock for CUSTOMER_SERVICE.department. 2) Next, we lock CUSTOMER _SERVICE.department for read. 3) We do an all-AMPs RETRIEVE step from CUSTOMER SERVICE.department by way of an all-rows scan with no residual conditions into Spool 1, which is built locally on the AMPs. The size of Spool 1 is estimated with low confidence to be 4 rows. The estimated time for this step is 0.15 seconds. 4) Finally, we send out an END TRANSACTION step to all AMPs involved in processing the request. The contents of Spool 1 are sent back to the user as the result of statement 1. The total estimated time 0.15 seconds. EXPLAIN 23

24 MODULE 4 24

25 Between... AND Range Test Operator—Numeric BETWEEN is inclusive. Select the name and the employee's manager number for all employees whose job codes are in the 430000 range. 25

26 BETWEEN... AND Range Test Operator—Character BETWEEN is inclusive. Select the last names of employees whose last name begins with 'R'. 26

27 BETWEEN is inclusive. Select the last names of employees whose last name begins with 'R'. BETWEEN... AND Range Test Operator—Character 27

28 Set Operator—IN Select the name and department for all employees in either department 401 or 403. 28

29 29

30 Set Operator—NOT IN Select the name and the department for all employees who are NOT members of departments 401 and 403. 30

31 31

32 Using NULL in a SELECT List the employee numbers for people with unknown extensions. List the employee numbers for people with known extensions. 32

33 Partial String Operator—LIKE Display the full name of employees whose last name begins with "Ra", using LIKE ‘Ra%’. 33

34 34

35 LIKE—Case-Blind Compare Display the full name of employees whose last name contains "Ra”, any combination of upper and lower case. Desired results: 35

36 What if last_name is defined as CASESPECIFIC? - Comparison reverts to case-specific! 36

37 LIKE Using Quantifiers Display the full name of all employees with both 'E' and 'S' in their last name. Quantifiers: ANY = any single condition must be met (OR) SOME = same as ANY ALL = all conditions must be met (AND) 37

38 LIKE—ESCAPE Character List all objects defined in the Teradata RDBMS Data Dictionary whose names contain “_” (underscore) as the second character. The first “_” (underscore) represents a wildcard—any single arbitrary character. The “Z_” sequence represents the “_” (underscore) as a single character, not as a wildcard. 38

39 Logical Operator—AND Display the name and employee number of employees who earn less than $35,000 per year and work in department 403. 39

40 40

41 Logical Operator—OR Display the name and the employee number for employees who either earn less than $35,000 annually or work in department 403. 41

42 Multiple AND... OR Select the name, department number, and job code for employees in departments 401 or 403, who have the job code 412101 or 432101. 42

43 Logical Operator—NOT Select the name and the employee number for all employees NOT in department 301. 43

44 Results: 44

45 Arithmetic Operators 45

46 Identify zip codes in the location table which end with four zeros. 46

47 Computed Values Make an alphabetical list of department 401 employees with their monthly salary. 47

48 BUILT-IN FUNCTIONS TIME is the current system time. USER is the current user. DATE is the current system date. 48

49 Literal, Constant, and Calculator Character Literals 49

50 Calculator Mode Numeric Constants 50

51 Using DATE in an SQL SELECT The facing page shows an example of a date calculation in a SELECT 51

52 Who has worked for the company for at least ten years? 52

53 Data Conversion Using CAST Numeric to numeric: Character to character: * Note: ANSI mode does not allow character truncation. 53

54 Data Conversions—Teradata Extension Teradata Extension: Can specify data attributes as well as ANSI data type in CAST. Display result as uppercase: * Note: ANSI mode does not permit character truncation. 54

55 MODULE 6 Subtitle here 55

56 IN Revisited Suppose you need to find all the employees who are department managers. You could manually look up all the managers from the department table, and then hard code them into this request: 56

57 SELECT Subquery You need to find all the employees who are department managers. You do not want to look them up manually. Use a SELECT subquery. Note: Subqueries always produce a DISTINCT list of values. 57

58 SELECT Subquery with AND Who are the department managers whose salaries are less than $35,000 and whose budget amounts are greater than $900,000? 58

59 SELECT Subquery with Quantifier ANY Who are the employees who work in support departments? 59

60 SELECT Subquery—Multiple Match Who are the department-level managers who are assigned to the same department that they manage? 60

61 EXISTS with Subquery Which departments have no employees? YES 61

62 Do any departments have no employees? Do any employees work in department 600? *** Query completed. No rows found 62

63 Naming a Column or Expression—AS Assigns a temporary name to a column or expression. Can be referenced elsewhere in the query. Column headings will default to the newly assigned name. 63

64 64

65 TITLE Attribute · Used to temporarily assign a name to a column. · Allows for character string titles that may contain blanks. · Allows up to three levels of title stacking. · Is a non-ANSI Teradata extension. 65

66 66

67 CHARACTERS Function Find all employees who have more than five characters in their first name. 67

68 68

69 TRIM Function List the employees who have exactly 4 characters in their last name. The data type of last_name is CHAR(20). Note: TRIM is most useful when performing string concatenation. 69

70 TRIM—ANSI vs. BTET Mode ANSI / Teradata Equivalence 70

71 71

72 FORMAT Phrase Format column output and override default format. 72

73 Format column output for a derived expression. Management has decided to give employee 1004 a $1,000 raise and wants to know what percent the increase will be: 73

74 FORMAT DATE in an SQL SELECT The facing page shows how to specify a date format in a SELECT statement. FORMAT DATE in an SQL SELECT 74

75 75

76 Extracting Portions of DATEs Using FORMAT: 76

77 Using MODULO: 77

78 Truncating CHARACTER Columns— ANSI vs. BTET Mode Show the last name, first name, and first initial of all employees named Brown. Sequence by the first initial. Using Data Type Conversion: In BTET session transaction mode: 78

79 In ANSI session transaction mode: 79

80 Attribute Functions To determine attributes for columns and expressions: TYPE TITLE FORMAT NAMED CHARACTERS Examples: 80

81 Inner Join Example—Solution Columns in the report fromemployee_number employee table:last_name Columns in the report fromdepartment_name department table: Tables are joined on theirdepartment_number common column: SELECT employee. employee_number,employee. last_name, department. department_name FROM employee INNER JOIN department ON employee. department_number = department. department_number ; 81

82 employee_numberlast_name department_name 1006 Steinresearch and development 1008 Kanieski research and development 1005 Ryan education 1004 Johnson customer support 1007 Villegas education 1003 Trader customer support Note: Only columns with identical names need to be qualified. Inner Join Example—Solution contd.. 82

83 Defining and Using Alias Names A temporary name for a TABLE or VIEW Defined in the FROM clause Useful for abbreviation of a long table name Required to join a table to itself Once the alias name is defined, it must be used throughout the SQL statement SELECT e.employee_number,e.last_name,d.department_name FROM employee e INNER JOIN department d ON e.department_number = d.department_number ; 83

84 employee_number last_name department_name 1006 Stein research and development 1008 Kanieski research and development 1005Ryan education 1004 Johnson customer support 1007 Villegas education 1003 Trader customer support Defining and Using Alias Names contd.. 84

85 Cross Joins A cross join is a join that requires no join condition. Cross joins are sometimes called product joins. Each participating row of one table is joined with each participating row of another table. Cross join syntax does not allow an ON clause. A WHERE clause may restrict which rows participate from either table. SELECT e.employee_number,d.department_number FROM employee e CROSS JOIN department d WHERE e.employee_number = 1008 ; 85

86 employee_number department_number 1008 301 1008 501 1008 402 1008 201 1008 302 1008 600 1008 401 1008 100 1008403 One employee matched with nine departments results in nine rows of output. Output is not meaningful. Cross Joins contd.. 86

87 Cartesian Products A completely unconstrained cross join is called a Cartesian product. Each row of one table is joined to each row of another table. A Cartesian product results from a CROSS JOIN without a WHERE clause. The output of a Cartesian product is rarely meaningful. Cartesian products can also result from an INNER JOIN with improper aliasing or improper join conditions. SELECT employee.employee_number,employee.department_number FROM employee CROSS JOIN department; Each employee row (26) matched with each department row (9) yields 234 rows of output. An 8,000,000 row table and a 50,000 row table would yield a 400,000,000,000 row answer set. 87

88 Useful Cartesian Products There are few real-world uses for Cartesian product joins. ANSI standards allow cross joins and thus Cartesian product joins. Cartesian product joins are useful for benchmarking system performance. Useful for tracking: – All air route information – All rate structures – All distances between a number of points 88

89 Inner Joins On Multiple Tables A join can have up to 64 participating tables or views. The number of participating tables or views determines the number of required join conditions. An n-table join requires n-1 join conditions. Omitting a join condition will result in a Cartesian product join. Example: SELECT e.last_name,d.department_name,j.description FROM employee e INNER JOIN department d ON e.department_number=d.department_number INNER JOIN job j ON e.job_code=j.job code; 89

90 last_name department_name description Daly software support Manager - Software Supp Runyon marketing sales Manager - Marketing Sale Trainer president Corporate President Brown customer support Dispatcher Inner Joins On Multiple Tables contd.. 90

91 Accidental Cartesian Products A Cartesian product can result from an inner join with improper aliasing: SELECT employee.employee_number,d.department_name,j.description FROM employee e INNER JOIN department d ON e.department_number=d.department_number; A Cartesian product can also result from an inner join with an improper join condition: SELECT e.employee_number,d.department_name FROM employee e INNER JOIN department d ON 3=3; Note: EXPLAIN all queries before allowing them to run in a production environment! 91

92 Self Joins · A self join combines the information from two or more rows of the same table into a single result row, effectively joining the table to itself. Who are all the Browns, and who do they report to? SELECT emp.first_name (TITLE 'Emp//First Name'),emp.last_name (TITLE 'Emp//Last Name) mgr.first_name (TITLE 'Mgr//First Name'),mgr.last_name (TITLE 'Mgr//Last Name') FROM employee emp INNER JOIN employee mgr ON emp.manager_employee_number = mgr.employee_number WHERE emp.last_name = 'Brown’ ; EmpEmp Mgr Mgr First Name Last Name Allen Brown Loretta Ryan Alan Brown James Trader 92

93 Determining Whether to Use Subquery or Join A subquery qualifies which rows SELECTed in the main query will be in the answer set. Data SELECTed in the subquery will not be included in the answer set. A join qualifies which rows from two or more tables will be matched to create rows of an answer set. The answer set can include data from one or more of the joined tables. 93

94 Subquery vs. Join Syntax List the first name, last name, and department number of all employees who work in research departments. Using a JOIN: SELECT employee.first_name,employee.last_name,employee.department_number FROM employee INNER JOIN department ON employee.department_number = department.department_number WHERE department.department_name LIKE ‘%Research%’; 94

95 SELECT first_name,last_name,department_number FROM employee WHERE department_number IN (SELECT department_number FROM department WHERE department_name LIKE ‘%Research%’); Using a SUBQUERY: Results: first_name last_name department_number Carol Kanieski 301 John Stein 301 Subquery vs. Join Syntax contd.. 95

96 Use EXPLAIN to Understand a Join EXPLAIN SELECT employee.first_name,employee.last_name,employee.department_number FROM employee INNER JOIN department ON employee.department_number = department.department_number WHERE department.department_name LIKE ‘%Research%’; Explanation 1)First, we lock a distinct CUSTOMER_SERVICE."pseudo table" for read on a RowHash to prevent global deadlock for CUSTOMER_SERVICE.employee. 2) Next, we lock a distinct CUSTOMER_SERVICE."pseudo table" for read on a RowHash to prevent global deadlock for CUSTOMER_SERVICE.department. 3) We lock CUSTOMER_SERVICE.employee for read, and we lock CUSTOMER_SERVICE.department for read. 96

97 4) We do an all-AMPs RETRIEVE step from CUSTOMER_SERVICE.employee by way of an all-rows scan with no residual conditions into Spool 2, which is redistributed by hash code to all AMPs. Then we do a SORT to order Spool 2 by row hash. The size of Spool 2 is estimated to be 24 rows. The estimated time for this step is 0.05 seconds. 5) We do an all-AMPs JOIN step from Spool 2 (Last Use) by way of an all-rows scan, which is joined to CUSTOMER_SERVICE.department with a condition of ("CUSTOMER_SERVICE.department.department_name LIKE %Research%'"). Spool 2 and CUSTOMER_SERVICE.department are joined using a merge join, with a join condition of ("Spool_2.department_number CUSTOMER_SERVICE.department.department_number"). The result goes into Spool 1, which is built locally on the AMPs. The size of Spool 1 is estimated to be 24 rows. The estimated time for this step is 0.18 seconds. 6) Finally, we send out an END TRANSACTION step to all AMPs involved in processing the request. The contents of Spool 1 are sent back to the user as the result of statement 1. The total estimated time is 0 hours and 0.23 seconds. Use EXPLAIN to Understand a Join contd.. 97

98 Use EXPLAIN to Understand a Subquery EXPLAIN SELECT first_name,last_name,department_number FROM employee WHERE department_number IN (SELECT department_number FROM department WHERE department_name LIKE ‘%Research%’); Explanation 1) First, we lock a distinct CUSTOMER_SERVICE."pseudo table" for read on a RowHash to prevent global deadlock for CUSTOMER_SERVICE.employee. 2) Next, we lock a distinct CUSTOMER_SERVICE."pseudo table" for read on a RowHash to prevent global deadlock for CUSTOMER_SERVICE.department. 3) We lock CUSTOMER_SERVICE.employee for read, and we lock CUSTOMER_SERVICE.department for read. 98

99 4) We do an all-AMPs RETRIEVE step from CUSTOMER_SERVICE.employee by way of an all-rows scan with no residual conditions into Spool 2, which is redistributed by hash code to all AMPs. Then we do a SORT to order Spool 2 by row hash. The size of Spool 2 is estimated to be 28 rows. The estimated time for this step is 0.05 seconds. 5) We do an all-AMPs JOIN step from Spool 2 (Last Use) by way of an all-rows scan, which is joined to CUSTOMER_SERVICE.department with a condition of ("CUSTOMER_SERVICE.department.department_name LIKE '%Research%'"). Spool 2 and CUSTOMER_SERVICE.department are joined using an inclusion merge join, with a join condition of ( "Spool_2.department_number = CUSTOMER_SERVICE.department.department_number"). The result goes into Spool 1, which is built locally on the AMPs. The size of Spool 1 is estimated to be 28 rows. The estimated time for this step is 0.20 seconds. The contents of Spool 1 are sent back to the user as the result of statement 1. The total estimated time is 0 hours and 0.24 seconds. Use EXPLAIN to Understand a Subquery contd.. 99

100 Module 9 - Outer Joins After completing this module, you will see how to: Perform a join involving two or more tables. Perform left, right, and full outer joins. 100

101 Inner Join An inner join returns an output row for each successful match between the join tables. SELECT D.Department_Number AS Dept,Department_Name,Last_name,E.Department_Number AS EmpDept FROM Department D INNER JOIN Employee E ON E.Department_Number= D.Department_Number; 101

102 Dept Department_Name Last_Name EmpDept 402 software support Crane 402 100 executive Trainer 100 501 marketing sales Runyon 501 301 research and development Stein 301 301 research and development Kanieski 301 Information about employees and their department names where the employee’s department number matches the existing departments. No information about employees who have no department number or an invalid department number. No information about departments which have no employees assigned to them. Inner Join contd.. 102

103 Outer Joins An outer join returns qualifying rows and nonmatching rows. SELECT D.Department_Number AS Dept,Department_Name,Last_name,E.Department_Number AS EmpDept FROM Employee E FULL OUTER JOIN Department D ON E.Department_Number=D.Department_Number; Dept Department_Name Last_Name EmpDept 600 new department ? ? 402 software support Crane 402 ? ? James 111 501 marketing sales Runyon 501 301 research and development Kanieski 301 ? ? Green ? 100 executive Trainer 100 301 research and development Stein 301 103

104 SELECT Statement Join Syntax SELECT cname [, cname, …] FROM tname [aname] [INNER] LEFT [OUTER] RIGHT [OUTER] FULL [OUTER] CROSS JOIN tname [aname] ON condition ; Where: cname Column or expression name tname Table or view name aname Alias for table or view name condition Criteria for the join 104

105 INNER JOIN All matching rows LEFT OUTER JOIN Table to the left is used to qualify, table on the right has nulls when rows do not match. RIGHT OUTER JOIN Table to the right is used to qualify, table on the left has nulls when rows do not match. FULL OUTER JOIN Both Tables are used to qualify and extended with nulls. CROSS JOIN Cartesian product SELECT Statement Join Syntax contd.. 105

106 LEFT Outer Join Example department_number department_name last_name 402 software support Crane 111 ? James 501 marketing sales Runyon 301 research and development Stein ? ? Green 100 executive Trainer 301 research and development Kanieski SELECT E.Department_Number,Department_Name,Last_Name FROM Employee E LEFT OUTER JOIN Department D ON E.Department_Number= D.Department_Number ; The results include: Employees who have valid department numbers Employees who have invalid department numbers Employees who have no value for their department number 106

107 RIGHT Outer Join Example SELECT E.Department_Number,Department_Name,Last_Name FROM Employee E RIGHT OUTER JOIN Department D ON E.Department_Number= D.Department_Number ; department_number department_name last_name 600 new department ? 402 software support Crane 100 executive Trainer 501 marketing sales Runyon 301 research and development Stein 301 research and development Kanieski The results include: Departments and their associated employees Departments which have no employees associated with them 107

108 Outer Joins of More Than Two Tables Each JOIN must have an associated ON clause. In joining more than two tables in an outer join, the ON clause needs to be placed appropriately so that the join operation can be evaluated correctly. SELECT last_name AS Employee,department_name AS Dept,descriptionAS Job FROM Department D RIGHT OUTER JOIN Employee E ON D.Department_Number = E.Department_Number LEFT OUTER JOIN Job J ON E.Job_Code = J.Job_Code ; The query returns all employees including: Employees without valid departments Employees with null departments Employees without valid job codes Employees with null job codes 108

109 ON Clause Placement The placement of the ON clause in the SELECT is important. The rules are: The first ON clause (from left to right) is evaluated first. An ON clause applies to the immediately preceding join operation. The same SELECT example could be written as: SELECT last_name AS Employee,department_name AS Dept,description AS Job FROM DepartmentD RIGHT OUTER JOIN Employee E LEFT OUTER JOIN Job J ON E.Job_Code = J.Job_Code ON D.Department_Number = E.Department_Number ; 109

110 The interpretation of the above statement is better understood when parentheses are used: SELECT last_name AS Employee,department_name AS Dept,description AS Job FROM Department D RIGHT OUTER JOIN ( Employee E LEFT OUTER JOIN Job J ON E.Job_Code = J.Job_Code ON D.Department_Number = E.Department_Number; ON Clause Placement contd.. 110

111 Module 10 Data Definition After completing this module, you will see how to: · Create, drop or alter a table. · Create or drop an index. · Create, drop, or alter table attributes. · Create, drop, or alter table constraints. 111

112 Data Definition Language Data Definition Language (DDL) is used by SQL to create, modify, and remove object definitions: Object: DDL Statements: Databases CREATE DATABASE MODIFY DATABASE DROP DATABASE Users CREATE USER MODIFY USER DROP USER Tables CREATE TABLE ALTER TABLE DROP TABLE Views CREATE VIEW REPLACE VIEW DROP VIEW Macros CREATE MACRO REPLACE MACRO DROP MACRO Indexes CREATE INDEX DROP INDEX 112

113 CREATE TABLE Elements CREATE TABLE syntax: CREATE TABLE employee ; Where: Create Table options Specify physical attributes of table: Fallback Journaling Freespace Datablocksize Column definitions Define each column in the table Table-level constraints Define Constraints: Primary key Unique CHECK conditions Foreign key Index definitions Specify indexes for physical access to data 113

114 Create Table Options Duplicate row options: – SET—no duplicate rows allowed – MULTISET—duplicate rows allowed Table protection options: – FALLBACK or NO FALLBACK PROTECTION – BEFORE JOURNAL (NO, single or DUAL) – AFTER JOURNAL (NO, single (LOCAL or NOT LOCAL) or DUAL) – WITH JOURNAL TABLE (Table Name) Space Management options – FREESPACE—percentage(%) of cylinder freespace – DATABLOCKSIZE—maximum block size for data blocks Example: CREATE MULTISET TABLE table_1, FALLBACK, NO JOURNAL, FREESPACE = 10 PERCENT, DATABLOCKSIZE = 16384 BYTES (field1 INTEGER); 114

115 Column Definitions Column name: – Name the column Data type: – Declare the column to be a character, byte, numeric, or graphic data type. Data type Attributes: – Specify DEFAULT, FORMAT, TITLE, NULL, CASESPECIFIC, UPPERCASE. Column Storage Attributes:; – Compress NULL values or a specified value. Column-level Constraint Attributes: – Specify the single column as a primary key or foreign key. – Specify the single column as unique (must be NOT NULL). – Specify constraint conditions on the column. 115

116 Column Data Type Choices 116

117 Example: CREATE TABLE emp_data (employee_number INTEGER,department_number SMALLINT,job_code INTEGER,last_name CHAR(20),first_name VARCHAR(20).,birthdate DATE,salary_amount DECIMAL(10,2). Column Data Type Choices contd.. 117

118 Column Data Type Attributes Data Type Attributes DEFAULT Specify default value in place of null WITH DEFAULT Specify use of system default value in place of null DEFAULT USER Store username of session FORMAT Default display format TITLE Default column title NOT NULL Disallow nulls, value required CASESPECIFIC Store as entered UPPERCASE Shift to uppercase for storage Example: CREATE TABLE emp_data (employee_number INTEGER NOT NULL.,user_name CHAR(25) DEFAULT USER,last_name CHAR(20) NOT NULL. WITH DEFAULT.,street_address VARCHAR(30) TITLE ‘Address’,city CHAR(15) DEFAULT ‘Boise’,state CHAR(2) WITH DEFAULT,birthdate DATE FORMAT ‘mm/dd/yy’.,salary_amount DEC(10,2),sex CHAR(1) UPPERCASE); 118

119 Column Storage Attributes Storage Attributes COMPRESS Null value is compressed to zero space. COMPRESS NULL Null value is compressed to zero space. COMPRESS Null value and value are compressed to zero space. Examples: CREATE TABLE emp_data (employee_number INTEGER,department_number INTEGER COMPRESS. CREATE TABLE bank_account_data (customer_id INTEGER,account_type CHAR(10) COMPRESS ‘SAVINGS’. 119

120 Column-level Constraints CONSTRAINT name—optional PRIMARY KEY No Nulls, No Dups UNIQUE No Nulls, No Dups CHECK Verify values or range REFERENCES Relates to other columns (foreign key) Example: CREATE TABLE employee_badge (emp_id INTEGER NOT NULL CONSTRAINT primary_1 PRIMARY KEY,id_badge_number INTEGER NOT NULL CONSTRAINT unique_1 UNIQUE,salary INTEGER CONSTRAINT check_1 CHECK (salary>0),job_code INTEGER CONSTRAINT ref_1 REFERENCES job (job_code) ); Note: A Primary Key constraint may only be placed on columns that are defined as NOT NULL. 120

121 Table-level Constraints An alternate way to set column constraints Useful for multi-column constraints Uniqueness Constraint: [CONSTRAINT name] PRIMARY KEY (col_list) [CONSTRAINT name] UNIQUE (col_list) Check Constraint: [CONSTRAINT name] CHECK boolean_condition) References Constraint: [CONSTRAINT name] FOREIGN KEY (col_list) REFERENCES tablename [(col_list)] 121

122 Table-level Constraints—Example If you perform a SHOW TABLE employee_badge; the DDL is different. Results are shown on the facing page. CREATE TABLE employee_badge (emp_id INTEGER NOT NULL,id_badge_num INTEGER NOT NULL,salaryINTEGER,job_code INTEGER,CONSTRAINT primary_1 PRIMARY KEY (emp_id),CONSTRAINT unique_1 UNIQUE (id)badge)num),CONSTRAINT check_1 CHECK (salary > 0 AND job_code BETWEEN 100000 AND 499999,CONSTRAINT ref_1 FOREIGN KEY (job_code) REFERENCES job (job_code) ); Note: PK and FK constraints are implemented as indexes. 122

123 Primary Key vs. Primary Index Primary Key One or more columns used to uniquely identify the rows in a table Used in conjunction with foreign keys to define the important column relationships in a database Always unique and cannot be null Not known to the Teradata RDBMS as keys Primary Index Teradata implements a primary key as an index. One or more columns used to distribute and locate the rows in a table. Choice of primary index will affect distribution, access and thus performance. Indexes (primary or secondary) may be used to enforce uniqueness. Indexes (primary or secondary) may be used to improve access. Indexes (primary or secondary) may be unique or non-unique. 123

124 Index Definitions A CREATE Table may specify: A Primary Index A Primary Key Both Neither Unspecified PI: If PK specified PK = UPI Else 1st UNIQUE col specified col = UPI All other UNIQUE cols col = USI specified Else 1st col specified col = NUPI Specified PI: If PK specified PK = USI And Each UNIQUE col specified col = USI PK Primary Key PI Primary Index UPI Unique Primary Index NUPI Non Unique Primary Index USI Unique Secondary Index 124

125 CREATE TABLE—Summary CREATE MULTISET TABLE emp(data,FALLBACK,NO BEFORE JOURNAL,NO AFTER JOURNAL,FREESPACE = 30,DATABLOCKSIZE = 10000 BYTES (employee_number INTEGER NOT NULL,department_number SMALLINT CONSTRAINT dep_check CHECK (department_number BETWEEN 100 AND 999) REFERENCES Department (department_number),job_code INTEGER COMPRESS,last_name CHAR(20) NOT NULL,first_name VARCHAR(20),street_address VARCHAR(30) TITLE ‘Address’,city CHAR(15) DEFAULT ‘Boise’ COMPRESS ‘Boise’,state CHAR(2) WITH DEFAULT,birthdate DATE FORMAT ‘mm/dd/yy’,salary_amount DECIMAL (10,2),sex CHAR(1) UPPERCASE,CONSTRAINT emp_key PRIMARY KEY (employee_number) ) INDEX (department_number) ; Example (full DDL for emp_data table): 125

126 HELP CONSTRAINT Given: the emp_data table defined earlier.SET FOLDLINE ON;.SET SIDETITLES ON; HELP CONSTRAINT emp_data.emp_key; Name EMP_KEY Type PRIMARY KEY Unique?Y Index Id 1 Column Names EMPLOYEE_NUMBER HELP CONSTRAINT emp_data.dep_check; Name DEP_CHECK Type CHECK Constraint CONSTRAINT "dep_check" CHECK ( ("department_number" >= 100 ) AND ("department_number" <= 999 ).SET FOLDLINE OFF;.SET SIDETITLES OFF; 126

127 DROP TABLE Example: DROP TABLE emp_data; Deletes all data in emp_data. Removes the emp_data definition from the Data Dictionary. DELETE FROM emp_data ALL; Deletes all data in emp_data. Table definition remains in the Data Dictionary. Compare to: 127

128 ALTER TABLE 1) ADDs and/or DROPs columns from an empty or populated table: ALTER TABLE emp_data ADD educ_level CHAR(1), ADD insure_type SMALLINT ; ALTER TABLE emp_data DROP educ_level, DROP insure_type ; 2) Changes the attribute options on existing columns: ALTER TABLE emp_data ADD birthdate FORMAT 'mmmBdd,Byyyy'‘ ; 3) Makes a NO FALLBACK table into a FALLBACK table, or vice versa: ALTER TABLE emp_data, FALLBACK ; 128

129 4) Combines various changes to the table structure and protection: ALTER TABLE emp_data, NO FALLBACK DROP insure_type, ADD educ_level CHAR(1) ; 5) Rename a column: ALTER TABLE emp_date RENAME birthdate TO birth_date ; ALTER TABLE contd.. 129

130 Changing Constraints ADD constraints: ALTER TABLE emp_data ADD CONSTRAINT CHECK (sex = ‘M’ OR sex = ‘F’); MODIFY a CHECK constraint: ALTER TABLE emp_data MODIFY CONSTRAINT sal_range CHECK (salary_amount > 0 AND salary_amount < 1000000); DROP constraints from an empty or populated table: ALTER TABLE emp_data DROP CONSTRAINT sal_range; Note: Constraints cannot be added if existing data violates proposed constraints. 130

131 CREATE a Secondary INDEX Create two secondary indexes on the employee table. Named unique secondary index (USI) on employee name: CREATE UNIQUE INDEX fullname (last_name, first_name) ON emp_data; Unnamed non-unique secondary index (NUSI) on job code: CREATE INDEX (job_code) ON emp_data; 131

132 HELP INDEX What are the indexes on the emp_data table?.SET FOLDLINE ON;.SET SIDETITLES ON; HELP INDEX emp_data; Unique?Y Primary//or//Secondary? P Column Namesemployee_number Index Id 1 Approximate Count 0 Index Nameemp_key Unique? N Primary//or//Secondary? S Column Names department_number Index Id 4 Approximate Count 0 Index Name ? 132

133 Unique? Y Primary//or//Secondary? S Column Names last_name,first_name Index Id 8 Approximate Count 0 Index Name fullname Unique? N Primary//or//Secondary? S Column Names job_code Index Id 12 Approximate Count 0 Index Name ?.SET FOLDLINE OFF;.SET SIDETITLES OFF; The values in the Index Id column correlate to the index numbers referenced in EXPLAIN text. HELP INDEX 133

134 DROP INDEX Delete all secondary indexes from the employee table. Dropping a named index: DROP INDEX FullName ON emp_data; Dropping an unnamed index: DROP INDEX (job_code) ON emp_data; 134

135 Module 11 - Data Manipulation After completing this module, you will see how to: Insert data rows into a table. Update existing rows in a table. Delete rows from a table. contd.. 135

136 INSERT Inserts a single row into a table. INSERT SELECT Inserts one or more rows into a table using values selected from other tables. UPDATE Changes column values in existing rows of a table. DELETE Removes rows from a table. Data Manipulation 136

137 INSERT Insert a new employee into the employee table: INSERT INTO employee VALUES(1210, NULL, 401, 412101, 'Smith', 'James', 890303, 460421, 41000); 137

138 Insert a new employee with only partial data: INSERT INTO employee (last_name, first_name, hire_date, birthdate, salary_amount, employee_number) VALUES ('Garcia', 'Maria', 861027, 541110, 76500.00, 1291) ; INSERT contd.. 138

139 INSERT SELECT · Used to copy rows from one table to another. · SELECT statement may define a subset of rows and/or a subset of columns. A simple INSERT SELECT: INSERT INTO emp_copy SELECT * FROM emp; Assumes: – emp and emp_copy have same definition – A complete replica of emp is required. A more complex INSERT SELECT: CREATE TABLE birthdays (empno INTEGER NOT NULL,lname CHAR NOT NULL,fname VARCHAR(30),birth DATE) UNIQUE PRIMARY INDEX (empno); INSERT INTO birthdays SELECT employee_number,last_name,first_name,birthdate FROM employee; 139

140 UPDATE Change employee 1010's department to 403, job code to 432101, and manager to 1005 in the employee table: 140

141 UPDATE employee SET department_number = 403,job_code = 432101,manager_employee_number = 1005 WHERE employee_number= 1010 ; UPDATE contd.. 141

142 UPDATE Using Subqueries or Joins Update the employee table to give everyone in all the support departments a 10% raise. We don't know the department numbers for all of the support departments. Using Subquery: UPDATE employee SET salary_amount = salary_amount * 1.10 WHERE department_number IN (SELECT department_number FROM sdepartment WHERE department_name LIKE '%Support%') ; Using Join: UPDATE employee SET salary_amount = salary_amount * 1.10 WHERE employee.department_number = department.department_number AND department_name LIKE '%Support%' ; 142

143 DELETE Remove all employees in department 301 from the employee table: DELETE FROM employee WHERE department_number = 301; 143

144 To delete ALL the data in the employee table: DELETE FROM employee; DELETE contd.. 144

145 DELETE Using Subqueries or JOINs Remove all of the employees who are assigned to a temporary department for which the department name is ‘Temp’. Using Subquery: DELETE FROM employee WHERE department_number IN (SELECT department _number FROM department WHEREdepartment_name = ‘Temp’) ; Using Join: DELETE FROM employee WHERE employee. department_number = department. department_number AND department. department_name = ‘Temp’ ; 145

146 Implicit transaction · Each SQL request is an implicit transaction by default. · Each failed request is automatically rolled back. Explicit transaction · Launched with explicit BEGIN TRANSACTION (BT) · Ended explicitly by: – END TRANSACTION (ET)—commit work done since BT – ROLLBACK—rollback work done since BT · Ended implicitly by: – Any request failure—rollback work done since BT Examples Implicit TransactionExplicit Transaction.LOGON INSERT row1; (txn #1) INSERT row2; (txn #2).LOGOFF.LOGON BT; (txn #1) INSERT row1; INSERT row2; ET;.LOGOFF Two transactions. Failure of one doesn’t affect other. One transaction. Failure of either will rollback to BT. Transaction Semantics—BTET Mode 146

147 Transaction Semantics—ANSI Mode Explicit transaction · Transaction is launched with first SQL request. · All transactions are explicitly ended. · Transaction ended explicitly by: – COMMIT WORK—commit work done since launch – ROLLBACK—rollback work done since launch Examples No Explicit EndingExplicit Ending.LOGON INSERT row1; (txn #1) INSERT row2;.LOGOFF.LOGON INSERT row1; (txn #1) INSERT row2; COMMIT WORK;.LOGOFF One transaction. Logoff without COMMIT— both INSERTs roll back. One transaction. Failure of either has no affect on the other. COMMIT commits successful requests only. 147

148 Transaction Semantics : ANSI vs. BTET Mode 148

149 DDL and Transactions · DDL must be the last statement in a transaction. · DDL must be the only statement in a macro..SET SESSION TRANSACTION ANSI DDL must be followed by COMMIT WORK or ROLLBACK WORK Example: CREATE TABLE test_1 (f1 INTEGER); COMMIT WORK;.SET SESSION TRANSACTION ANSI In implicit transaction, DDL is a single-statement transaction Example: CREATE TABLE test_1 (f1 INTEGER); In explicit transaction, DDL must be followed by ET (End Transaction) Example: BT; CREATE TABLE test_1 (f1 INTEGER); ET; 149

150 Module 12 - Macros After completing this module, you will see how to: Create and use a macro. Modify and drop a macro. Create a parameterized macros. Use macros to provide secure access to data. 150

151 Macros contain one or more prewritten SQL statements. Macros are a Teradata extension to ANSI SQL. Macros are stored in the Teradata Data Dictionary. Macros can be executed from any viable SQL front-end, including: – Queryman – BTEQ – Preprocessor – CLI – LOGON Startup – Another macro Users can be granted exec privileges on macros in lieu of update privileges on base tables or views. Macros 151

152 CREATE MACRO macroname AS Define a macro and store (... );it on the DD. EXECute macroname; Execute statements within a macro. SHOW MACRO macroname; Display a macro. REPLACE MACRO macroname ASApply changes to a macro (... );or create a new macro. DROP MACRO macroname; Remove a macro definition from the DD. EXPLAIN EXEC macroname; Display EXPLAIN text for the macro's execution. Macro-related commands: 152

153 CREATE, EXECUTE, DROP Macro Create a macro to generate a birthday list for department 201: CREATE MACRO birthday_list AS (SELECT last_name,first_name,birthdate FROM employee WHERE department_number = 201 ORDER BY birthdate ; ); To execute the birthday list macro: EXEC birthday_list; last_name first_name birthdate Morrissey Jim 43/04/29 Short Michael 47/07/07 Department 201 no longer needs a birthday list: DROP MACRO birthday_list; 153

154 Changing a Macro Modify department 201's birthday list to have a minor sort on last name. 1. Show the definition of the MACRO birthday_list: SHOW MACRO birthday_list; 2. Resulting output contains: ®REPLACE MACRO birthday_list AS (SELECT last_name,first_name,birthdate FROM employee WHERE department_number = 201 ORDER BY birthdate ®,last_name;); 3. Change "CREATE" to "REPLACE" and include the minor sort. CREATE MACRO birthday_list AS (SELECT last_name,first_name,birthdate FROM employee WHERE department_number = 201 ORDER BY birthdate;); 4. Submit the REPLACE STATEMENT. 5. EXEC the replaced MACRO. 154

155 Simple Parameterized Macros Parameterized macros allow substitutable variables. Values for these variables are supplied at runtime. Example: CREATE MACRO dept_list (dept INTEGER) AS ( SELECT last_name FROM employee WHERE department_number = :dept; ); To execute: EXEC dept_list (301); Results: last_name Stein Kanieski Kubic 155

156 Parameterized Macro to INSERT Data CREATE MACRO new_dept ( dept INTEGER, budget DEC(10,2) DEFAULT 0, name CHAR(30), mgr INTEGER) AS ( INSERT INTO department ( department_number, department_name, budget_amount, manager_employee_number) VALUES ( :dept, :name, :budget, :mgr ) ; SELECT department_number (TITLE ‘Number’),department_name (TITLE ‘Name’),budget_amount (TITLE ‘Budget’),manager_employee_number (TITLE ‘Manager’) FROM department WHERE department_number = :dept ; ); 156

157 EXECUTE the INSERT Macro (With Positional Parameter Values) When using this MACRO you must: Input data in the same order as specified in the macro parameter list. Provide the exact number of parameters specified in the list. Use positional commas or NULL for empty columns and filler parameters. The following events occur: Data types are checked for compatibility with the CREATE TABLE data types. NULLS are checked for validity against the CREATE TABLE column definitions. Defaulting is applied if specified in the CREATE macro. Defaulting from the CREATE TABLE is overridden. EXEC new_dept (505,610000.00,'Marketing Research', 1007); Number Name Budget Manager 505 Marketing Research 610000.00 1007 EXEC new_dept (102,, 'Payroll', NULL); Number Name Budget Manager 102 Payroll.00 ? 157

158 EXECUTE the INSERT Macro—Using Parameter Names The parameterized input can be scrambled in any order by including the parameter name with the value, as follows: EXEC new_dept( name = 'accounting',budget = 425000.00,dept = 106 ) ; Number Name Budget Manager 106 accounting 425000.00 ? 158

159 Using Macros to Preserve Integrity CREATE MACRO new_employee( number INTEGER,MGR INTEGER, dept INTEGER, job INTEGER,lastname CHAR (20),firstname VARCHAR (30),hired DATE, birth DATE,salary DECIMAL (10, 2)) AS (ROLLBACK WORK `Invalid Hire' WHERE (:hired - :birth) / 365 < 21; ROLLBACK WORK `Invalid Department' WHERE :dept NOT IN (SELECT department_number FROM department WHERE department_number = :dept); ROLLBACK WORK `Invalid Job Code' WHERE :job NOT IN (SELECT job_code FROM job WHERE job_code = :job); INSERT INTO employee ( employee_number manager_employee_number, department_number,job_code, last_name, first_name, hire_date, birthdate,salary_amount ) VALUES ( :number, :mgr, :dept, :job, :lastname :firstname, :hired, :birth,:salary ); ) ; 159

160 Using Constraints to Preserve Integrity Ensure that employees meet the following requirements: At least 21 years old when hired. Have a valid department number. Have a valid job code. CREATE TABLE employee (employee_number INTEGER, …,salary_amount DECIMAL (10,2),CHECK (hire_date - birthdate) /365 > = 21),FOREIGN KEY (department_number) REFERENCES department (department_number),FOREIGN KEY (job_code) REFERENCES job (job_code) ); 160

161 Module 13 - Aggregating Groups After completing this module, you will see how to: Aggregate data by one or more columns to summarize results. Use the GROUP BY clause. 161

162 Aggregate Operators COUNT Count SUM Sum AVG Average MAX Maximum MIN Minimum Aggregates can ONLY produce SINGLE-LINE answers. Aggregate operations ignore NULLs. SELECT COUNT ( salary_amount ) (TITLE `COUNT'),SUM ( salary_amount ) (TITLE ‘SUM//SALARY'),AVG ( salary_amount ) (TITLE `AVG//SALARY'),MAX ( salary_amount ) (TITLE `MAX//SALARY'),MIN ( salary_amount ) (TITLE `MIN//SALARY') FROM employee ; SUM AVG MAX MIN COUNT SALARY SALARY SALARY SALARY 6 213750.00 35625.00 49700.00 29250.00 162

163 The Benefits of Aggregates—Problem Find the total salary for all employees in each department. The task can be accomplished by qualifying the SELECT with a WHERE clause for each department. SELECT SUM (salary_amount) FROM employee WHERE department_number = 401 ; Sum (salary_amount) 74150.00 SELECT SUM (salary_amount) FROM employee WHERE department_number = 403 ; Sum (salary_amount) 80900.00 SELECT SUM (salary_amount) FROM employee WHERE department_number = 301 ; Sum (salary_amount) 58700.00 163

164 The Solution: GROUP BY Create a summary showing total salary for each department. Hint: Think of GROUP BY as FOR EACH SELECT department_number,SUM (salary_amount) FROM employee GROUP BY department_number ; department_number Sum (salary_amount) 401 74150.00 403 80900.00 301 58700.00 Any non-aggregates in the SELECT list must also appear in the GROUP BY clause. If you violate this rule, you'll get the message: ERROR: 3504 Selected non-aggregate values must be part of the associated group. GROUP BY eliminates detail rows from the answer set. 164

165 Group BY and the WHERE Clause The WHERE clause eliminates some rows before GROUP BY puts them into desired groupings. What are the total salaries for departments 401 and 403? SELECT department_number,SUM (salary_amount) FROM employee WHERE department_number IN (401,403) GROUP BY department_number ; department_number Sum (salary_amount) 403 80900.00 401 74150.00 165

166 GROUP BY and ORDER BY Find the total number of employees and the highest, lowest and average salary in each department. Order the results by department number. SELECT department_number (TITLE `DEPT'),COUNT (*) (TITLE `#_EMPS'),SUM (salary_amount) (TITLE `TOTAL') (FORMAT `zz,zzz,zz9.99'),MAX (salary_amount) (TITLE `HIGHEST') (FORMAT `zz,zzz,zz9.99'),MIN (salary_amount) (TITLE `LOWEST') (FORMAT `zz,zzz,zz9.99'),AVG (salary_amount) (TITLE `AVERAGE') (FORMAT `zz,zzz,zz9.99') FROM employee GROUP BY department_number ORDER BY department_number; DEPT #_EMPS TOTAL HIGHEST LOWEST AVERAGE 301 3 116,400.00 57,700.00 29,250.00 38,800.00 401 7 245,575.00 46,000.00 24,500.00 35,082.14 403 6 233,000.00 49,700.0031,000.00 38,833.33 166

167 GROUP BY on Multiple Columns GROUP BY produces only ONE level of a subtotal. What are the total salaries for departments 401 and 403, by job code? SELECT department_number,job_code,SUM (salary_amount) FROM employee WHERE department_number IN (401,403) GROUP BY 1, 2 ORDER BY 1, 2 ; department_number job_code SUM (salary_amount) 401 411100 37850.00 401 412101 107825.00 401 412102 56800.00 401 413201 43100.00 403 431100 31200.00 403 432101 201800.00 167

168 GROUP BY and HAVING Condition The HAVING condition selects only the groups from a GROUP BY clause that satisfy a conditional expression. Which departments have an average salary of less than $36,000? The report is generated using the HAVING clause: SELECT department_number (TITLE `DEPT'),COUNT (*) (TITLE `#_EMPS'),SUM (salary_amount) (TITLE `TOTAL') (FORMAT `zz,zzz,zz9.99'),MAX (salary_amount) (TITLE `HIGHEST') (FORMAT `zz,zzz,zz9.99'),MIN (salary_amount) (TITLE `LOWEST') (FORMAT `zz,zzz,zz9.99’),AVG (salary_amount) (TITLE `AVERAGE') (FORMAT `zz,zzz,zz9.99') FROM employee GROUP BY department_number HAVING AVG (salary_amount) < 36000; DEPT #_EMPS TOTAL HIGHEST LOWEST AVERAGE 4017 7 245,575.00 46,000.00 24,500.00 35,082.14 168

169 WHERE Eliminates some or all rows immediately. Only rows which satisfy a WHERE condition are eligible for inclusion in groups. GROUP BY Puts the qualified rows into the desired groupings. HAVING Eliminates some (or all) of the groupings. ORDER BY Sorts the final groups for output. (ORDER BY is not implied by GROUP BY). Aggregating Groups Summary 169

170 Module 14- Totals and Subtotals After completing this module, you will see how to: Create subtotals using WITH … BY. Create final totals using WITH. Eliminate duplicate results using the DISTINCT option. 170

171 Using WITH... BY for Subtotals WITH... BY Creates subtotal lines for a detail list Differs from GROUP BY in that detail lines are not eliminated Allows subtotal "breaks" on more than one column Generates automatic sort on all BY columns Is a Teradata extended feature 171

172 Creating a Report Using WITH... BY Display employee name and salary with subtotals by department. SELECT last_name AS NAME,salary_amount AS SALARY,department_number AS DEPT FROM employee WITH SUM (salary) BY DEPT; NAME SALARY DEPT Stein 29450.00 301 Kanieski 29250.00 301 -------------- Sum(SALARY)58700.00 Johnson 36300.00 401 Trader 37850.00 401 -------------- Sum(SALARY)74150.00 Villegas 49700.00 403 Ryan 31200.00 403 -------------- Sum(SALARY)80900.00 172

173 WITH... BY Multiple Aggregates Display employee name and salary with subtotals and averages by department. SELECT last_name AS NAME,salary_amount AS SALARY,department_number AS DEPT FROM employee WITH SUM (salary) (TITLE `Dept Total'),AVG (salary) (TITLE `Dept Avg ') BY DEPT ; NAME SALARY DEPT Stein 29450.00 301 Kanieski 29250.00 301 -------------- Dept Total 58700.00 Dept Avg 29350.00 Johnson 36300.00 401 Trader 37850.00 401 -------------- Dept Total 74150.00 Dept Avg 37075.00 Villegas 49700.00 403 Ryan 31200.00 403 -------------- Dept Total 80900.00 Dept Avg 40450.00 173

174 WITH... BY Multiple Subtotal Levels Report the total salary by department, and by job code within department, for departments 401 and 501. Show the detail salary for each employee. SELECT department_number AS Dept,job_code AS Job,employee_number AS Empl,salary_amount AS Sal FROM employee WHERE department_number IN (401, 501) WITH SUM (salary_amount) (TITLE `Job Total') BY Job WITH SUM (salary_amount) (TITLE `DEPT TOTAL') BY Dept; 174

175 Dept Job Empl Sal 401 411100 1003 37850.00 Job Total 37850.00 401 412101 1010 46000.00 401 412101 1001 25525.00 401 412101 1004 36300.00 Job Total 107825.00 401 412102 1013 24500.00 401 412102 1022 32300.00 Job Total 56800.00 401 413201 1002 43100.00 Job Total 43100.00 DEPT TOTAL 245575.00 501 511100 1017 66000.00 Job total 66000.00 501 512101 1015 53625.00 501 512101 1018 54000.00 501 512101 1023 26500.00 Job total 134125.00 DEPT TOTAL 200125.00 WITH... BY Multiple Subtotal Levels contd.. 175

176 Creating Final Totals Using WITH WITH without BY creates a grand total. Display the employee numbers and salary amounts for department 301, with a final total for the department. SELECT employee_number,salary_amount FROM employee WHERE department_number = 301 WITH SUM(salary_amount) (TITLE `GRAND TOTAL') ORDER BY employee_number ; employee_number salary_amount 1006 29450.00 1008 29250.00 GRAND TOTAL 58700.00 176

177 DISTINCT Modifier Used with an aggregate on a single expression. With the DISTINCT modifier: SELECT employee_number,department_number,manager_employee_number AS manager FROM employee WHERE employee_number BETWEEN 1003 AND 1008 WITH COUNT (DISTINCT manager) (TITLE `TOTAL MANAGERS'); employee_number department_number manager 1006 301 1019 1005 403 801 1003 401 801 1007 403 1005 1008 301 1019 1004 401 1003 TOTAL MANAGERS 4 177

178 SELECT employee_number,department_number,manager_employee_number (NAMED manager) FROM employee WHERE employee_number BETWEEN 1003 AND 1008 WITH COUNT (manager) (TITLE `TOTAL MANAGERS') ; Without the DISTINCT modifier: DISTINCT Modifier contd.. 178

179 WITH... BY, WITH and ORDER BY Show the salary for each employee with subtotals by department, a final total, and sort by name. SELECT last_name AS NAME,salary_amount AS SALARY,department_number AS DEPT FROM employee WITH SUM (SALARY) BY DEPT WITH SUM (SALARY) (TITLE ‘GRAND TOTAL’) ORDER BY NAME; NAME SALARY DEPT Kanieski 29250.00 301 Stein 29450.00 301 ------------- Sum (SALARY) 58700.00 Johnson 36300.00 401 Trader 37850.00 401 ------------- Sum (SALARY) 74150.00 Ryan 31200.00 403 Villegas 49700.00 403 ------------- Sum (SALARY) 80900.00 ------------- GRAND TOTAL 213750.00 179

180 Creating Final Totals Using WITH and GROUP BY Show the total and average salaries for each department, plus a final total and average for the company. SELECT department_number,SUM (salary_amount),AVG (salary_amount) FROM employee WHERE department_number IN (301,401,403) GROUP BY department_number WITH SUM (salary_amount),AVG (salary_amount) ORDER BY department_number ; dept_no SUM (salary_amount) AVG (salary_amount) 301 58700.00 29350.00 401 74150.00 37075.00 40380900.00 40450.00 GRAND TOTAL 213750.00 35635.00 180

181 WITH... BY and WITH Summary Teradata extension not found in ANSI SQL. WITH summarylist BY breaklist ASC/DESC – Creates total and/or subtotal lines for detail list function. – Summarylist can specify more than one column. – Breaklist can specify more than one column. – Implies ORDER BY on the breaklist columns. – WITH... BYs determine the MAJOR sort keys. – An SQL statement can have several WITH BY clauses. – The lowest level of MAJOR sort is the first WITH BY. – ORDER BY specifies any additional MINOR sorts. WITH summarylist – Provides a final or grand total. – Summarylist can specify more than one column. 181

182 Module 15 Correlated Subqueries and Derived Tables After completing this module, you will see how to: Write a correlated subquery. Specify a derived table in a SELECT or ABORT statement. Specify aggregates in the WHERE clause. 182

183 Correlated Subqueries A correlated subquery is a subquery whose outer query results are processed a row at a time, against the subquery result. The subquery result is computed for each row processed. Find the employee with the highest salary in each department. SELECT last_name,department_number AS deptno,salary_amount FROM employee ee WHERE salary_amount = (SELECT MAX (salary_amount) FROM employee em WHERE ee.department_number = em.department_number); last_name deptno salary_amount Runyon 501 66000.00 Rogers 401 46000.00 Trainer 100 100000.00 Villegas403 49700.00 Daly 402 52500.00 Morrissey 201 38750.00 Kubic 301 57700.00 Rogers 30 56500.00 183

184 More Correlated Subqueries Find all employees whose salary is greater than the department average salary. SELECT last_name,salary_amount (Format ‘$$$,$99.99’) FROM employee ee WHERE salary_amount > (SELECT AVG (salary_amount) FROM employee em WHERE ee.department_number = em.department_number); Results: last_name salary_amount Trader $37,850.00 Runyon $66,000.00 Wilson $53,625.00. How can you show the average departmental salary in this report? Use Derived Tables (discussed later in this module). 184

185 Correlated Subqueries Using EXISTS Which job codes are not assigned to any employee? Using NOT IN: SELECT job_code FROM job WHERE job_code NOT IN (SELECT job_code FROM employee) ; job_code 104202 104201 412103 322101 Using NOT EXISTS: SELECT job_code FROM job WHERE NOT EXISTS (SELECT * FROM employee ee WHERE ee.job_code = job.job_code); job_code 104202 104201 412103 322101 185

186 Correlated Subqueries and Joins Show the employee number, department number, and salary of all department managers who have the highest salary in their department. SELECT d.manager_employee_number (TITLE ‘mgr_emp_#’),d.department_number,e.salary_amount FROM department d INNER JOIN employee e ON e.employee_number = d.manager_employee_number WHERE e.salary_amount = (SELECT MAX (salary_amount) FROM employee em WHERE d.department_number = em.department_number); mgr_emp_# department_number salary_amount 1019 301 57700.00 1017 501 66000.00 1011 402 52500.00 1016 302 56500.00 801 100 100000.00 186

187 Using Interim Tables Show all employees whose salary is greater thanthe company average. First, create an interim table. CREATE TABLE my_temp (avgsal DECIMAL (10,2)); Populate the table with one row. INSERT INTO my_temp SELECT AVG (salary_amount) FROM employee; Perform the query. SELECT e.last_name,e.salary_amount (FORMAT ‘$,$$$,$99.99’),t.avgsal (FORMAT ‘$,$$$,$99.99’) FROM employee e,my_temp t WHERE e.salary_amount > t.avgsal ORDER BY 2 DESC; Drop the interim table. DROP TABLE my_temp; Results: last_name salary_amount avgsal Trainer $100,000.00 $42,386.54 Runyon $66,000.00 $42,386.54... 187

188 Using Derived Tables Derived tables are temporary tables that are created and dropped as part of the query. Allows use of aggregates in the WHERE clause. Show all employees whose salary is greater than the company average. SELECT last_name,salary_amount (FORMAT ‘$,$$$,$99.99’),avgsal (FORMAT ‘$,$$$,$99.99’) FROM (SELECT AVG (salary_amount) FROM employee) my_temp (avgsal),employee WHERE salary_amount > avgsal ORDER BY 2 DESC; Results: last_name salary_amount avgsal Trainer $100,000.00 $42,386.54 Runyon $66,000.00 $42,386.54... Note: Using derived tables requires one step instead of four steps, as seen with interim tables. 188

189 Using Derived Tables with Groups Show all employees whose salary is greater than the departmental average. SELECT last_name AS last,salary_amount (FORMAT ‘$,$$$,$99.99’)AS sal,department_number AS dep,avgsal (FORMAT ‘$,$$$,$99.99’) FROM (SELECT AVG (salary_amount),department_number FROM,employee GROUP BY department_number) my_temp (avgsal, deptno) employee WHERE sal > avgsal ORDER BY 2 DESC; Results: last sal dep avgsal Runyon $66,000.00 501 $50,031.25 Kubic $57,700.00 301 $38,800.00 Ratzlaff $54,000.00 501 $50,031.25.. Note: (This was previously done using a correlated subquery. Correlated subquery was not able to produce AVGSAL column.) 189

190 Module 16- Set Operations After completing this module, you will see how to: Use the Union operator. Use the Intersect operator. Use the Except operator. 190

191 Set Operations Returns an answer set containing rows that are in all the sets generated by each SELECT operation. Combines results of all SELECT statements, displaying duplicate rows only one time in the answer set. Excludes the results of the second SELECT from the results of the first SELECT in the answer set. 191

192 UNION Operator Who is manager 1019 and who works for him? SELECT first_name,last_name,'employee' (TITLE 'employee//type') FROM employee WHERE manager_employee_number = 1019 UNION SELECT first_name,last_name,' manager ' FROM employee WHERE employee_number = 1019 ORDER BY 2; first_name last_name employee_type CarolKanieski employee Ron Kubic manager John Stein employee 192

193 INTERSECT Operator List all department managers having subordinate employees. SELECT manager_employee_number FROM employee INTERSECT SELECT manager_employee_number FROM department ORDER BY 1; manager_employee_number 801 1003 1005 1011 1017 1019 1025 193

194 EXCEPT Operator List all department managers who do not have subordinate employees. SELECT manager_employee_number FROM department EXCEPT SELECT manager_employee_number FROM employee ORDER BY 1 ; manager_employee_number 1016 1099 194

195 Set operators—Additional Rules Set operators may be used in most SQL constructs. Evaluation order can be manipulated with parentheses. Each SELECT statement must have a FROM table_name. GROUP BY applies only to an individual SELECT. GROUP BY does not apply to the result set as a whole. Duplicates are eliminated unless the ALL option is used. 195

196 Module 17 - CASE Expressions After completing this module, you will be able to: Return alternate values using the CASE expression. Use special variations of the CASE expression: – NULLIF – COALESCE 196

197 CASE Expression CASE allows for conditional processing of returned rows. CASE returns a single result for each row processed. Each row is evaluated against each WHEN clause. First match returns a result for that row. If no match, ELSE result is produced for that row. Valued CASE format: CASE value-expr WHEN expr1 THEN result1 WHEN expr2 THEN result2 : ELSE resultn END 197

198 Calculate the fraction of the total salary of all employees represented by the salaries of Dept. 401. SELECT SUM( CASE department_number WHEN 401 THEN salary_amount ELSE 0 END) / SUM(salary_amount) FROM employee; (Sum( )/Sum(salary_amount)) 2.22834717118098E-001 CASE Expression contd.. 198

199 Valued CASE Statement Get the ratio of Dept 401 salaries to all employees. SELECT CAST (SUM( CASE department_number WHEN 401 THEN salary_amount ELSE 0 END) / SUM(salary_amount) AS numeric (2,2)) AS sal_ratio FROM employee; sal ratio.22 Get the total salaries for departments 401 and 501. SELECT CAST (SUM(CASE department_number WHEN 401 THEN salary_amount WHEN 501 THEN salary_amount ELSE 0 END) / AS NUMERIC (9,2)) AS total_sals_401_501 FROM EMPLOYEE; total sals 401 501 4457000.00 199

200 Searched CASE Statement Searched CASE format: CASE WHEN condition1 THEN value-expr1 WHEN condition2 THEN value-expr2 : ELSE value-expr END SELECT last_name,,CASE WHEN salary_amount < 30000 THEN 'Under $30K' WHEN salary_amount < 40000 THEN 'Under $40K' WHEN salary_amount <50000 THEN 'Under $50K' ELSE ’< = $50K' END FROM employee ORDER BY salary_amount; last_name Phillips Under $30K Crane Under $30K Hoover Under $30K Rabbit Under $30K Kanieski Under $30K Stein Under $30K Lombardo Under $40K Ryan Under $40K Machado Under $40K Short Under $40K Johnson Under $40K TraderUnder $40K Hopkins Under $40K Morrissey Under $40K Charles Under $40K Brown Under $50K Rogers Under $50K Villegas Under $50K Daly Over $50K Wilson Over $50K Ratzlaff Over $50K Rogers Over $50K Kubic Over $50K Runyon Over $50K Trainer Over $50K 200

201 Searched CASE Example Calculate the fraction of the total salaries represented by departments 401 and 501. Allow for a 10% salary increase for the employees in department 501. SELECT SUM ( CASE WHEN department_number = 401 THEN salary_amount WHEN department_number = 501 THEN salary_amount * 1.1 ELSE 0 END) / SUM (CASE WHEN department_number = 501 THEN salary_amount * 1.1 ELSE salary_amount END ) (FORMAT ‘Z.99’) AS sal_ratio FROM employee; sal ratio.42 201

202 NULLIF Expression NULLIF returns a null if an equal condition is determined. SELECT call_number,labor_hours (TITLE `ACTUAL HOURS’),NULLIF (labor_hours, 0) (TITLE `NULLIF ZERO HOURS') FROM call_employee ORDER BY labor_hours; call_number ACTUAL HOURS NULLIF ZERO HOURS 4 ? ? 5 ? ? 6 ? ? 3 0 ? 2 4.04.0 1 8.58.5 202

203 NULLIF Expression contd.. 203

204 NULLIF for Division Find the ratio of hourly billing rate to hourly cost rate for all "analyst" jobs. Without NULLIF: SELECT description,hourly_billing_rate / hourly_cost_rate (TITLE 'Billing to Cost Ratio') FROM job WHERE description like ‘%analyst%’; Error Message: Division by zero in an expression involving job.hourly_cost_rate. With NULLIF: SELECT description,hourly_billing_rate /(NULLIF(hourly_cost_rate, 0)) (TITLE 'Billing to Cost Ratio') FROM job WHERE description like '%analyst%‘ ; description Billing to Cost Ratio Software Analyst 1.29 System Support Analyst ? System Analyst 1.14 204

205 COALESCE Expression Returns first non-null value in an expression list. Show office phone number if present, else show home phone. Use COALESCE: SELECT name,COALESCE (office_phone, home_phone) FROM phone_table; To convert possible NULL value to zero: SELECT course_name,COALESCE (num_students,0) (TITLE ‘# Students’) FROM class_schedule; course_name # Students Teradata SQL 17 Physical DB Design 0 To convert possible NULL value to ‘NULL VALUE’: SELECT course_name,COALESCE (num_students, ’NULL VALUE’) (TITLE ‘# Students’) FROM class_schedule; course_name # Students Teradata SQL 17 Physical DB Design NULL VALUE 205

206 COALESCE and NULLIF with Aggregates SELECT AVG (labor_hours) (TITLE 'DEFAULT//AVG'),AVG (NULLIF ( labor_hours, 0)) (TITLE 'NIZ//AVG'),AVG (COALESCE ( labor_hours, 0)) (TITLE 'ZIN//AVG') (FORMAT 'zz,zzz.z'),COUNT ( labor-hours) (TITLE 'DEFAULT//COUNT') (FORMAT 'zz9'),COUNT (NULLIF ( labor_hours, 0)) (TITLE 'NIZ//COUNT') (FORMAT 'zz9'),COUNT (COALESCE ( labor_hours, 0)) (TITLE 'ZIN//COUNT') (FORMAT 'zz9') FROM call_employee; DEFAULT NIZ ZIN AVG AVG AVG COUNT COUNT COUNT 4.2 6.2 2.1 3 2 6 206

207 Module 18 - Views After completing this module, you will see how to: Create a view. Use a view to provide secure access to data. Drop or modify a view. List several reasons for using views. 207

208 What is a View? A view is a virtual table. It may define a subset of rows of a table. It may define a subset of columns of a table. It may reference more than one table. Data is neither duplicated nor stored separately for a view. View definitions are stored in the Data Dictionary, not in the user’s own space. 208

209 CREATING and Using Views Create a view of the employees in department 403 to use for both read and update. Limit the view to an employee’s number, last name, and salary. CREATE VIEW emp_403 AS SELECT employee_number,last_name,salary_amount FROM employee WHERE department_number = 403; To read from this view: SELECT * FROM emp_403 ; employee_number last_name salary_amount 1005 Ryan 31200.00 1007 Villegas 49700.00 1020 Charles 39500.00 1009 Lombardo 31000.00 1012 Hopkins 37900.00 1024 Brown 43700.00 To update from this view: UPDATE emp_403 SET salary_amount = 100000 WHERE last_name = 'Villegas' ; 209

210 Join View A Join view consists of columns from more than one table. Create a Join view of the employee and call_employee tables for call dispatch use. CREATE VIEW employee_call AS SELECT employee.employee_number,last_name,first_name,call_number,call_status_code,assigned_date,assigned_time,finished_date,finished_time FROM employee INNER JOIN call_employee ON call_employee.employee_number = employee.employee_number; 210

211 Who is employee 1002 and what calls has he answered? SELECT last_name,first_name,call_number FROM employee_call WHERE employee_number = 1002; last_name first_name call_number Brown Alan 9 Join View contd.. 211

212 Using Views to Rename Columns Create a view which is a single-department subset of the employee table, that also shortens the typing on queries. To select rows using this view: CREATE VIEW shortcut (emp, dept, last, first, sal) AS SELECT employee_number,department_number,last_name,first_name,salary_amount FROM employee WHERE department_number = 201; To select rows using this view: SELECT last,sal FROM shortcut ORDER BY last DESC; Lastsal Short 38750.00 Morrissey 34700.00 To update rows using this view: UPDATE shortcut SET sal = 100000.00 WHERE emp = 1019; 212

213 Changing a View Change the shortcut view to include only department 301. 1) Display the current view definition from the DD..EXPORT REPORT FILE = shortcut.ddl SHOW VIEW shortcut ; 2) The view definition is exported to file shortcut.ddl. CREATE VIEW shortcut (emp, dept, last, first, sal) AS SELECT employee_number,department_number,last_name,first_name,salary_amount FROM employee WHERE department_number = 201; 3) Change CREATE to REPLACE and make the desired code changes.  REPLACE VIEW shortcut (emp, dept, last, first, sal) AS SELECT employee_number,department_number,last_name,first_name,salary_amount FROM employee  WHERE department_number = 301; 213

214 Using Views to FORMAT and TITLE Create a view for department 201 with presentable titles and formatting. Show salary amount as a monthly figure. CREATE VIEW report AS SELECT employee_number AS Emp (FORMAT `9999'),department_number AS Dept (FORMAT `999'),last_name AS Name,first_name (TITLE ‘’),salary_amount / 12 AS Monthly_Salary (FORMAT `$$$,$$9.99') FROM employee WHERE department_number = 201; To select rows using this view: SELECT * FROM report ORDER BY monthly_salary; Emp Dept Name Monthly_Salary 1025 201 Short Michael $2,891.67 1021 201 Morrissey James $3,229.17 214

215 An Aggregate View Create a view that summarizes salary information by department. CREATE VIEW deptsals AS SELECT department_number AS department,SUM (salary_amount) AS salary_total,AVG (salary_amount) AS salary_average,MAX (salary_amount) AS salary_max,MIN (salary_amount) AS salary_min FROM employee GROUP BY department_number; 215

216 Note: Aggregate and derived columns must be given names. To select the average salary for all departments, using the view: SELECT department,salary_average FROM deptsals; department salary_average 100 100000.00 201 36725.00 403 38833.33...... 401 35082.14 … … An Aggregate View contd.. 216

217 An Aggregate View using HAVING Modify the deptsals view to include only those departments with an average salary of less than $36,000. REPLACE VIEW deptsals AS SELECT department_number AS department,SUM (salary_amount) AS salary_total,AVG (salary_amount) AS salary_average,MAX (salary_amount) AS salary_max,MIN (salary_amount) AS salary_min FROM employee GROUP BY department_number HAVING AVG (salary_amount) < 36000 ; 217

218 To select all departments with average salaries less than $36,000, use the view: SELECT department,salary_average FROM deptsals; department salary_average 401 35082.14 An Aggregate View using HAVING contd.. 218

219 Joins on Views with Aggregates (1 of 2) Create a view to show the purchase history of items by customer for 1996. CREATE VIEW cust_prod_sales (custno, item, sales) AS SELECT customer_number,item_number,SUM (item_sales_amount) FROM sales_hist_1996 GROUP BY 1,2 ; SELECT * FROM cust_prod_sales; custno item sales 1 345 5,000 1567 12,000 2 123 6,000 2 567 7,000 3567 13,000 219

220 Joins on Views with Aggregates (2 of 2) Show by name which companies purchased more than $10,000 worth of item 567. SELECT customer_name,sales (format ‘ZZZ,ZZ9’) FROM cust_prod_sales a INNER JOIN customer b ON b.customer_number = a.custno WHERE a.sales > 10000 AND a.item = 567; customer_name sales A TO Z Communications 12,000 First American Bank 13,000 220

221 Restrictions on Views An index cannot be CREATEd on a view. A view cannot contain an ORDER BY clause. The WHERE clause of a SELECT against a view can reference all aggregated columns of that view. Derived columns and aggregate columns must have an AS clause. A view cannot be used to UPDATE if it contains: – Data from more than one table (JOIN VIEW) – The same column twice – Derived columns – A DISTINCT clause – A GROUP BY clause 221

222 Summary of Views Advantages: Provide an additional level of security/authorization. Help control read and update privileges. Are not affected if columns are added to a table. Are not affected if a column is dropped from a table unless the dropped column is referenced by the view. Simplify end-user access. Suggestions: Create at least one view for each base table. Create query views as needed (ad hoc). 222

223 Module 19- String Functions After completing this module, you will see how to: Extract strings using SUBSTRING. Combine strings using concatenation. Locate the starting position of substrings using POSITION. 223

224 String Expressions String Operator: Concatenation (||) Putting character strings together String Functions: SUBSTRING Obtaining a section of a character string POSITION Locating a character position in a string TRIM* Trims blanks from a string UPPER* Converts a string to uppercase * Covered in a previous module 224

225 SUBSTRING Function Older syntax (prior to V2R2.0): Result: SELECT SUBSTR (‘catalog’,5,3); ‘log’ New syntax (V2R2.0): Result: SELECT SUBSTRING(‘catalog’ FROM 5 FOR 3);‘log’ · Both functions are available · SUBSTRING is ANSI standard Result SUBSTRING(‘catalog’ FROM 5 FOR 4) ‘log’ SUBSTRING(‘catalog’ FROM 0 FOR 3) ‘ca’ SUBSTRING(‘catalog’ FROM -1 FOR 3) ‘c’ SUBSTRING(‘catalog’ FROM 8 FOR 3) 0 length string SUBSTRING(‘catalog’ FROM 1 FOR 0) 0 length string SUBSTRING(‘catalog’ FROM 5 FOR -2) error (without a FOR clause) SUBSTRING(‘catalog’ FROM 0) ‘catalog’ SUBSTRING(‘catalog’ FROM 10) 0 length string SUBSTRING(‘catalog’ FROM -1) ‘catalog’ SUBSTRING(‘catalog’ FROM 3) ‘talog’ 225

226 Using SUBSTRING in a List Display the first initial and last name of all employees in department 403, sorted by last name. SELECT SUBSTRING (first_name FROM 1 FOR 1) (TITLE 'FI'),last_name FROM employee WHERE department_number = 403 ORDER BY last_name ; FI last_name L Ryan A Villegas 226

227 Using SUBSTRING with INTEGERs Convert INTEGERs to character strings when doing a substring on an INTEGER column. When integer fields are converted to CHAR, a sign character is added and the value is rightaligned, for example: + 1 2 7 ( no. of dependents ) BYTEINT + 0 0 2 1 3 ( area code ) SMALLINT + 0 0 0 5 5 5 4 1 3 4 ( phone ) INTEGER To select 3 digit area codes: SELECT DISTINCT SUBSTRING (area_code FROM 4 FOR 3) AS AREA_CODE FROM location_phone ORDER BY 1; AREA_CODE 202 212 213 312 313 415 609 617 718 804 919 227

228 Using SUBSTRING in a WHERE Clause Find all the customers in the location table whose zip codes end with four zeros. SELECT customer_number,zip_code (FORMAT '9(9)') FROM location WHERE SUBSTRING (zip_code FROM 8 FOR 4) = '0000' ; customer_number zip_code 13 001210000 10 940710000 228

229 String Concatenation Use concatenation to display the first and last names for employees in department 403: first_name is defined as VARCHAR(30) last_name is defined as CHAR(20) SELECT first_name l l ' ' l l last_name ( TITLE 'EMPLOYEE') FROM employee WHERE department_number = 403 ; EMPLOYEE Arnando Villegas Loretta Ryan 229

230 String Concatenation with SUBSTRING and TRIMyy Use SUBSTRING with concatenation to display the first initial and last name of employees in department 403. SELECT SUBSTRING (first_name FROM 1 FOR 1 ) l l '. ' l l last_name ( TITLE 'EMPLOYEE') FROM employee WHERE department_number = 403 ; EMPLOYEE L. Ryan A. Villegas SELECT TRIM (last_name) l l ', ' l l first_name ( TITLE 'EMPLOYEE') FROM employee WHERE department_number = 403 ; EMPLOYEE Ryan, Loretta Villegas, Arnando Use TRIM with concatenation to drop the spaces after the last names. 230

231 POSITION—Character String Position Finds the position where a substring begins within a string. Display a list of departments where the word "SUPPORT" appears in the department name, and list the starting position of the word. SELECT department_name,POSITION('SUPPORT' IN department_name,) FROM department WHERE POSITION('SUPPORT' IN department_name,) > 0 ORDER BY department_number ; department_name Position('SUPPORT' IN department_name,) customer support 10 software support 10 231

232 Using SUBSTRING and POSITION Display the first name and last name for each person in the contact table. Contact_name is a VARCHAR column. SELECT SUBSTRING (contact_name FROM POSITION (', ' IN contact_name) +2) l l ' ' l l SUBSTRING (contact_name FROM 1 FOR POSITION (', ' IN contact_name) -1) (TITLE 'Contact Names') FROM contact; Contact Names Alison Torres Ginny Smith Nancy Dibble Connie Brayton Jack Hughes James LeBlanc 232

233 Module 20 Using the System Calendar 233

234 After completing this module, a student should see how to: Create views based on the system calendar. Perform historical queries relative to any date. Return information based on any calendar based quantification. 234

235 SQL has limited ability to do date arithmetic. There is a need for more complex, calendar-based calculations. How does this quarter compare to same quarter last year? How many shoes do we sell on Sundays vs. Saturdays? During which week of the month do we sell the most pizzas? What is our sales forecast for the month of October? Extends properties of DATE data type by joining to Calendar. Easily joined to other tables, i.e. dimension of a star schema. High performance - limited I/O. Has advantages over user-defined calendars. Statistics are created for materialized table for join planning. Only necessary rows are materialized for the calendar. Why a System Calendar? 235

236 Calendar Table Layout Columns frm system Calender calendar_date DATE UNIQUE (Standard Teradata date) day_of_week BYTEINT, (1-7, where 1 = Sunday) day_of_month BYTEINT, (1-31) day_of_year SMALLINT, (1-366) day_of_calendar INTEGER, (Julien days since 01/01/1900) weekday_of_month BYTEINT, (nth occurrence of day in month week_of_month BYTEINT, (partial week at start of month is 0) week_of_year BYTEINT, (0-53) (partial week at start of year is 0) week_of_calendar INTEGER, (0-n) (partial week at start is 0) month_of_quarter BYTEINT, (1-3) month_of_year BYTEINT, (1-12) month_of_calendar INTEGER, (1-n) (Starting Jan, 1900) quarter_of_year BYTEINT, (1-4) quarter_of_calendar INTEGER, (Starting Q1, 1900) year_of_calendar SMALLINT, (Starting 1900) Columns from the System Calendar: System Calendar is a 4-level nested view of dates Underlying table is Sys_calendar.Caldates: 236

237 System Calendar is a 4-level nested view of dates Underlying table is Sys_calendar.Caldates: Has one column called ‘cdate’ - DATE data type Has one row for each date of calendar Unique Primary Index is cdate Each level of view adds intelligence to date System calendar includes Jan 1, 1900 through Dec. 31, 2100 237

238 One Row in the Calendar SELECT * FROM Sys_calendar.Calendar WHERE calendar_date = CURRENT_DATE; calendar_date 98/09/21 day_of_week 2 day_of_month 21 day_of_year 264 day_of_calendar 36058 weekday_of_month 3 week_of_month 3 Week_of_year 38 week_of_calendar 5151 month_of_quarter 3 month_of_year 9 month_of_calendar 1185 quarter_of_year 3 quarter_of_calendar 395 year_of_calendar 1998 238

239 Using The Calendar Show total sales of item 10 reported in Q1 of 1998. SELECT ds.itemid,SUM(ds.sales) FROM sys_calendar.calendar sc,daily_sales ds WHERE sc.calendar_date = ds.salesdate AND sc.quarter_of_year = 1 AND sc.year_of_calendar = 1998 AND ds.itemid = 10 GROUP BY 1 ; itemid Sum(sales) ----------- -------------- 10 4050.00 239

240 Salesdate is joined to the system calendar Calendar determines if this date meets criteria Is it a Quarter 1 date? Is it a 1998 date? If yes on both, add this sales amount to result 240

241 Using Today’s View CREATE VIEW today AS ( SELECT * FROM sys_calendar.calendar WHERE calendar.calendar_date = CURRENT_DATE); This view contains a single row for today’s date. Row contains all calendar information for today. For reporting relative to today, use a Today view 241

242 Today View Get total sales for item 10 for the current month. SELECT SUM(ds.sales) FROM sys_calendar.calendar sc,daily_sales ds,today td WHERE sc.calendar_date = ds.salesdate AND sc.month_of_calendar = td.month_of_calendar AND ds.itemid = 10; Sum(sales) ---------------- 2550.00 242

243 Query Relative to Today Example of query relative to today's date (Sept 21, 1998) Therefore, requires the Today view. Compare sales for item 10 during the current and previous month for both this year and last. SELECT sc.year_of_calendar AS ”Year",sc.month_of_year AS ”Month",ds.itemid,SUM(ds.sales) FROM sys_calendar.calendar sc,daily_sales ds,today td WHERE sc.calendar_date = ds.salesdate AND ((sc.month_of_calendar between td.month_of_calendar - 1 AND td.month_of_calendar) OR (sc.month_of_calendar between td.month_of_calendar - 13 AND td.month_of_calendar - 12)) AND ds.itemid = 10 GROUP BY 1,2,3 ORDER BY 1,2; 243

244 Year Month itemid Sum(sales) ----------- ----------- ----------- ---------------- 1997 8 10 1950.00 1997 9 10 2100.00 1998 8 10 2200.00 19989 10 2550.00 244

245 Group Results By Week of Month SELECT sc.year_of_calendar AS ”Year",sc.month_of_year AS ”Month",sc.week_of_month AS "Week of//Month",ds.itemid,SUM(ds.sales) FROM sys_calendar.calendar sc,daily_sales ds,today td WHERE sc.calendar_date = ds.salesdate AND ((sc.month_of_calendar between td.month_of_calendar - 1 AND td.month_of_calendar) OR (sc.month_of_calendar between td.month_of_calendar - 13 AND td.month_of_calendar - 12)) AND ds.itemid = 10 GROUP BY 1,2,3,4 ORDER BY 1,2,3; 245

246 Week of Year Month Month itemid Sum(sales) ----------- ----------- ----------- ----------- ---------------- 1997 8 0 10 350.00 1997 8 1 10 600.00 1997 8 2 10 550.00 1997 8 3 10 150.00 1997 8 4 10 200.00 1997 8 5 10 100.00 1997 9 0 10 750.00 1997 9 2 10 1000.00 1997 9 3 10 350.00 1998 8 0 10 150.00 1998 8 1 10 1050.00 1998 8 2 10 550.00 1998 8 3 10 150.00 1998 8 4 10 200.00 1998 8 5 10 100.00 1998 9 0 0 400.00 1998 9 1 10 800.00 1998 9 2 10 550.00 1998 9 3 10 450.00 1998 9 4 10 350.00 246

247 Comparing Relative Weeks Show sales for item 10 for the first full week of the previous month and the corresponding week from a year ago. SELECT sc.year_of_calendar AS ”Year",sc.month_of_year AS ”Month",sc.week_of_month AS "Week of//Month",ds.itemid,SUM(ds.sales) FROM sys_calendar.calendar sc,daily_sales ds,today td WHERE sc.calendar_date = ds.salesdate AND sc.week_of_month = 1 AND ((sc.month_of_calendar = td.month_of_calendar - 1) OR (sc.month_of_calendar = td.month_of_calendar - 13)) AND ds.itemid = 10 GROUP BY 1,2,3,4 ORDER BY 1,2; 247

248 Week of Year Month Month itemid Sum(sales) ------------ ----------- ----------- ------------ ----------- 1997 8 1 10 600.00 1998 8 1 10 1050.00 248

249 Aggregates Based on Day-of-Week Show sales figures for item 10 for all Sundays during the current and previous months where total daily sales is greater than $150. SELECT sc.calendar_date AS ”Date",sc.week_of_month AS "Week of//Month",'Sunday',ds.itemid,SUM(ds.sales) FROM sys_calendar.calendar sc,daily_sales ds,today td WHERE sc.calendar_date = ds.salesdate AND sc.day_of_week = 1 AND ((sc.month_of_calendar = td.month_of_calendar) OR (sc.month_of_calendar = td.month_of_calendar - 1)) AND ds.itemid = 10 HAVING sum(ds.sales) > 150 GROUP BY 1,2,3,4 ORDER BY 1,2; 249

250 Week of Date Month 'Sunday' itemid Sum(sales) ------------ --------- ---------- ----------- -------------- 98/08/02 1 Sunday 10 200.00 98/09/06 1 Sunday 10 350.00 98/09/20 3 Sunday 10 450.00 98/09/27 4 Sunday 10 350.00 250

251 Comparing Weeks Show sales of item 10 for the current and preceding week and the same weeks last year. SELECT sc.year_of_calendar AS ”Year",sc.month_of_year AS ”Month",sc.week_of_month AS ”Week",ds.itemid,SUM(ds.sales) FROM sys_calendar.calendar sc,daily_sales ds,today td WHERE sc.calendar_date = ds.salesdate AND ((sc.week_of_calendar between td.week_of_calendar - 1 AND td.week_of_calendar) OR (sc.week_of_calendar between td.week_of_calendar - 53 AND td.week_of_calendar - 52)) AND ds.itemid = 10 GROUP BY 1,2,3,4 ORDER BY 1,2,3; 251

252 year month week itemid Sum(sales) ----------- ----------- ----------- ----------- ----------- 1997 9 2 10 1000.00 1997 9 3 10 350.00 1998 9 2 10 550.00 1998 9 3 10 450.00 252

253 Using A Day-of-Week Table CREATE TABLE day_of_week (numeric_day INTEGER,char_day CHAR(9)) UNIQUE PRIMARY INDEX (numeric_day); INSERT INTO day_of_week VALUES (1, 'Sunday'); INSERT INTO day_of_week VALUES (2, 'Monday'); INSERT INTO day_of_week VALUES (3, 'Tuesday'); INSERT INTO day_of_week VALUES (4, 'Wednesday'); INSERT INTO day_of_week VALUES (5, 'Thursday'); INSERT INTO day_of_week VALUES (6, 'Friday'); INSERT INTO day_of_week VALUES (7, 'Saturday'); Show average sales for item 10 for each day of the week. SELECT dw.char_day AS "Day of// Week",AVG(ds.sales) AS Avgsal FROM daily_sales ds,sys_calendar.calendar sc,day_of_week dw WHERE sc.calendar_date = ds.salesdate AND sc.day_of_week = dw.numeric_day GROUP BY 1; 253

254 Day of Week Avgsal --------- ----------- Thursday 250.00 Friday 272.22 Wednesday 350.00 Monday 275.00 Sunday 295.00 Tuesday 285.71 Saturday 325.00 254

255 Module 21 Basic On-Line Analytical Functions 255

256 After completing this module, a student should see how to: Perform data mining using standard SQL. Combine OLAP functions with standard SQL functions. Perform cumulative functions, moving functions and rankings 256

257 On-Line Analytical Functions Purpose: To permit data mining on a database via SQL. OLAP functions available under Teradata (V2R3) include: CSUM - (Cumulation) MAVG - (Moving Averages) MSUM - (Moving Sums) MDIFF - (Moving Differences) RANK - (Rankings) QUANTILE - (Quantiles) SAMPLE - (Sampling) MLINREG - (Moving Linear Regression) OLAP functions are similar to aggregate functions: Operate on groups of rows (like GROUP BY clause). Can filter groups using QUALIFY (like HAVING clause). OLAP functions are unlike aggregate functions: Return data value for each qualifying row - not group. May not be performed within subqueries. INSERT/SELECT populations OLAP functions may be performed on: Tables (Perm, Temp, Derived) Views 257

258 Cumulative Sum Cumulative sum (CSUM) computes a running or cumulative total of a column’s value. SELECT salesdate, sales, CSUM(sales, salesdate) FROM daily_sales WHERE salesdate BETWEEN 980101 AND 980228 AND itemid = 10; Create a running daily total for item 10 for Jan and Feb 1998: salesdate sales Csum -------------- ----------- ----------- 98/01/01 150.00 150.00 98/01/02 200.00 350.00 98/01/03 250.00 600.00 98/01/05 350.00 950.00 98/01/10 550.00 1500.00 98/01/21 150.00 1650.00 98/01/25 200.00 1850.00 98/01/31 100.00 1950.00 98/02/01 150.00 2100.00 98/02/03 250.00 2350.00 98/02/06 350.00 2700.00 98/02/17 550.00 3250.00 98/02/20 450.00 3700.00 98/02/27 350.00 4050.00 CSUM(colname, sort list) Note: System Calendar not required for this query What if you wanted to reset the cumulation for each month? 258

259 Cumulative Sums With Reset Create a running daily sales total for item 10 for Jan and Feb 1998 and reset the cumulation for a change in month: SELECT salesdate, sales, CSUM(sales, salesdate) FROM daily_sales ds, sys_calendar.calendar sc WHEREds.salesdate = sc.calendar_date AND sc.year_of_calendar = 1998 AND sc.month_of_year in (1,2) AND ds.itemid = 10 GROUP BY sc.month_of_year; 259

260 salesdate sales Csum ------------- ----------- ----------- 98/01/01 150.00 150.00 98/01/02 200.00 350.00 98/01/03 250.00 600.00 98/01/05 350.00 950.00 98/01/10 550.00 1500.00 98/01/21 150.00 1650.00 98/01/25 200.00 1850.00 98/01/31 100.00 1950.00 98/02/01 150.00 150.00 98/02/03 250.00 400.00 98/02/06 350.00 750.00 98/02/17 550.00 1300.00 98/02/20 450.00 1750.00 98/02/27 350.00 2100.00 A Join to the System Calendar is needed to isolate the month. GROUP BY clause causes reset of cumulation. Reset cumulation 260

261 Moving Averages Show a moving average on a 7 day window for sales of item 10: Uses current row and preceding n-1 rows. Uses all preceding rows if less than n-1. Sort ascending by sortlist column(s) is default. SELECT salesdate, itemid, sales, MAVG(sales, 7, salesdate) FROM daily_sales; 261

262 salesdate itemid sales MAvg ------------- ----------- ----------- ----------- 98/01/01 10 150.00 150.00 98/01/02 10 200.00 175.00 98/01/03 10 250.00 200.00 98/01/05 10 350.00 237.50 98/01/10 10 550.00 300.00 98/01/21 10 150.00 275.00 98/01/25 10 200.00 264.29 98/01/31 10 100.00 257.14 98/02/01 10 150.00 250.00 98/02/03 10 250.00 250.00 98/02/06 10 350.00 250.00 98/02/17 10 550.00 250.00 98/02/20 10 450.00 292.86 : : Computes moving AVG of a column where n (width) <= 4096 MAVG(colname, n, sortlist) Avg of 7 rows Avg of 2 rows 262

263 Moving Sums Show a moving sum on a 3 day window for sales of item 10: Uses current row and preceding n-1 rows. Uses all preceding rows if less than n-1. Sort ascending by sortlist column(s) is default. SELECT salesdate, itemid, sales, MSUM(sales, 3, salesdate) FROM daily_sales; 263

264 salesdate itemid sales MSum ------------- ----------- ----------- ----------- 98/01/01 10 150.00 150.00 98/01/02 10 200.00 350.00 98/01/03 10 250.00 600.00 98/01/05 10 350.00 800.00 98/01/10 10 550.00 1150.00 98/01/21 10 150.00 1050.00 98/01/25 10 200.00 900.00 98/01/31 10 100.00 450.00 98/02/01 10 150.00 450.00 98/02/03 10 250.00 500.00 98/02/06 10 350.00 750.00 98/02/17 10 550.00 1150.00 98/02/20 10 450.00 1350.00 98/02/27 10 350.00 1350.00 : : Computes moving SUM of a column where n (width) <= 4096. MSUM(colname, n, sortlist) Sum of 3 rows Sum of 2 rows 264

265 Moving Differences Show a moving difference for a 3 day width on sales of item 10: Uses current row and preceding nth row. Value is null if there is no preceding nth row. Sort ascending by sortlist column(s) is default. SELECT salesdate, itemid, sales, MDIFF(sales, 3, salesdate) FROM daily_sales; salesdate itemid sales MDiff ------------- ----------- ----------- ----------- 98/01/01 10 150.00 ? 98/01/02 10 200.00 ? 98/01/03 10 250.00 ? 98/01/05 10 350.00 200.00 98/01/10 10 550.00 350.00 98/01/21 10 150.00 -100.00 98/01/25 10 200.00 -150.00 98/01/31 10 100.00 -450.00 98/02/01 10 150.00.00 98/02/03 10 250.00 50.00 98/02/06 10 350.00 250.00 98/02/17 10 550.00 400.00 98/02/20 10 450.00 200.00 98/02/27 10 350.00.00 : : 265

266 Computes moving difference of a column where n (width) <= 4096. MDIFF(colname, n, sortlist) Difference of 2 rows 266

267 Sales Table Sales table is kept small for simplicity. Used in many of OLAP examples in this module. Shows summarized amounts for each store by product. Data limited to 3 stores and 5 products. CREATE TABLE salestbl (storeid INTEGER, prodid CHAR(1), sales DECIMAL(9,2)); SELECT * FROM salestbl ORDER BY 1,2; storeid prodid sales ----------- --------- ------------- 1001 A 100000.00 1001 C 60000.00 1001 D 35000.00 1001 F 150000.00 1002 A 40000.00 1002 C 35000.00 1003 B 65000.00 1003 C 20000.00 1003 D 50000.00 Salestbl 11 Rows 267

268 Simple and Qualified Rankings Show the ranking of product sales for store 1001: SELECT storeid, prodid, sales, RANK(sales) FROM salestbl WHERE storeid = 1001; WHERE clause qualifies rows to be ranked. storeid prodid sales Rank ----------- --------- -------------- ----------- 1001 F 150000.00 1 1001 A 100000.00 2 1001 C 60000.00 3 1001 D 35000.00 4 Ranking applied - default highest amount is low rank #. Default sort sequence is descending by ranking column (sales). Qualified ranking QUALIFY the ranking for the top 3 sales amounts only Get top 3 sales - any product in any store: Simple ranking 268

269 SELECT storeid, prodid, sales, RANK(sales) FROM salestbl QUALIFY RANK(sales) <= 3 ; storeid prodid sales Rank ----------- ----------- ------------- ----------- 1001 F 150000.00 1 1001 A 100000.00 2 1003 B 65000.00 3 269

270 Ranking With Qualification and GROUP BY SELECT storeid, prodid, sales, RANK(sales) FROM salestbl GROUP BY storeid QUALIFY RANK(sales) <= 3; storeid prodid sales Rank ----------- ------ -------------- ----------- 1001 F 150000.00 1 1001 A 100000.00 2 1001 C 60000.00 3 1002 A 40000.00 1 1002 C 35000.00 2 1002 D 25000.00 3 1003 B 65000.00 1 1003 D 50000.00 2 1003 A 30000.00 3 GROUP BY clause controls scope, i.e., rank sales within store. (Note -- no aggregation is done in this query) Without GROUP BY, scope would default to sales. QUALIFY the ranking for the top 3 sales amounts per store. Default sort sequence is descending by ranking column (sales). Due to GROUP BY, sort is by sales (DESC) within store (ASC). Get top three selling products by store: 270

271 Variations On A Ranking SELECT storeid,prodid,sales,RANK(sales) FROM salestbl GROUP BY storeid, prodid QUALIFY RANK(sales) <= 3 ; storeid prodid sales Rank ----------- --------- ------------- ----------- 1001 A 100000.00 1 1001 C 60000.00 1 1001 D 35000.00 1 1001 F 150000.00 1 1002 A 40000.00 1 1002 C 35000.00 1 1002 D 25000.00 1 1003 A 30000.00 1 1003 B 65000.00 1 1003 C 20000.00 1 1003 D 50000.00 1 271

272 Ranking With Aggregations Get top three selling items across all stores: Cannot combine OLAP functions and aggregates. Alternative - use temporary or derived tables. SELECT prodid, SUM(sales) AS sumsales, rank(sumsales) FROM salestbl GROUP BY 1 QUALIFY RANK(sumsales) <= 3; ** Failure ** STAT FUNCTIONS not allowed with AGGREGATES SELECT dt.Prodid, dt.Sumsales, RANK(dt.Sumsales) FROM (SELECT a.prodid, SUM(a.sales) FROM salestbl a GROUP BY 1) AS dt(Prodid, Sumsales) QUALIFY RANK(Sumsales) <= 3; Get top three selling items across all stores: Prodid Sumsales Rank --------- --------------- ----------- A 170000.00 1 F 150000.00 2 C 115000.00 3 272

273 GROUP BY in derived table is for aggregation, not RANK. No GROUP BY in main query, thus scope is Sumsales. Default is Order By sumsales Desc. 273

274 Low Order Ranking Get top three selling items across all stores (repeated): SELECT dt.Prodid, dt.Sumsales, RANK(dt.Sumsales) FROM (SELECT a.prodid, SUM(a.sales) FROM salestbl a GROUP BY 1) AS dt(Prodid, Sumsales) QUALIFY RANK(Sumsales) <= 3; prodid Sumsales Rank --------- --------------- ----------- A 170000.00 1 F 150000.00 2 C 115000.00 3 274

275 Get three poorest selling items across all stores: SELECT dt.Prodid, dt.Sumsales, RANK(dt.Sumsales) FROM (SELECT a.prodid, SUM(a.sales) FROM salestbl a GROUP BY 1) AS dt(Prodid, Sumsales) QUALIFY RANK(Sumsales ASC) <= 3; prodid sumsales Rank ---------- ------------- ----------- B 65000.00 5 D 110000.00 4 C 115000.00 3 Order By sumsales Ascending gives bottom three rows. Note rank value outputs may be greater than 3. ‘Qualify’ says ‘Rank by sales ascending and give me first three. 275

276 Ranking and Order By Get three poorest selling items across all stores, order by Prodid: SELECT dt.Prodid, dt.Sumsales, RANK(dt.Sumsales) FROM (SELECT a.prodid, SUM(a.sales) FROM salestbl a GROUP BY 1) AS dt(Prodid, Sumsales) QUALIFY RANK(Sumsales ASC) <= 3 ORDER BY 1; Prodid Sumsales Rank --------- -------------- ----------- B 65000.00 5 C 115000.00 3 D 110000.00 4 Same three spool rows are generated as prior example List is now ordered by ascending product id 276

277 If query test is changed to <=2, which rows are output? SELECT dt.Prodid, dt.Sumsales, RANK(dt.Sumsales) FROM (SELECT a.prodid, SUM(a.sales) FROM salestbl a GROUP BY 1) AS dt(Prodid, Sumsales) QUALIFY RANK(Sumsales ASC) <= 2 ORDER BY 1; Prodid Sumsales Rank --------- -------------- ----------- B 65000.00 5 D 110000.00 4 277

278 Module 22 Advanced On-Line Analytical Functions 278

279 After completing this module, a student should see how to: Perform data mining using standard SQL. Combine OLAP functions with standard SQL functions. Perform statistical samplings, forecasts and quantiles. 279

280 On-Line Analytical Functions OLAP functions available under Teradata (V2R3) include: CSUM - (Cumulation) MAVG - (Moving Averages) MSUM - (Moving Sums) MDIFF - (Moving Differences) RANK - (Rankings) QUANTILE - (Quantiles) SAMPLE - (Sampling) MLINREG - (Moving Linear Regression) CREATE TABLE salestbl ( storeid INTEGER, prodid CHAR(1), sales DECIMAL(9,2)); SELECT * FROM salestbl ORDER BY 1,2; 280

281 storeid prodid sales ----------- --------- ------------- 1001 A 100000.00 1001 C 60000.00 1001 D 35000.00 1001 F 150000.00 1002 A 40000.00 1002 C 35000.00 1002 D 25000.00 1003 A 30000.00 1003 B 65000.00 1003 C 20000.00 1003 D 50000.00 Salestbl 11 Rows 281

282 Using Quantiles Quantiles are used to divide rows into a number (n) of partitions. Show each product percentile based on total sales: SELECT t.prodid, t.sumsales, QUANTILE (100,sumsales) FROM (SELECT a.prodid, SUM(a.sales) FROM salestbl a GROUP BY 1) AS t(prodid, sumsales); prodid sumsales Quantile --------- ------------- ----------- B 65000.00 0 D 110000.00 20 C 115000.00 40 F 150000.00 60 A 170000.00 80 Derived table used to do aggregation. Sort by ascending quantile column is report default. Width = 100, quantile range is 0-99. 282

283 Show products in the 60+ percentile based on total sales: SELECT t.prodid, t.sumsales, QUANTILE (100,sumsales) FROM (SELECT a.prodid, SUM(a.sales) FROM salestbl a GROUP BY 1) AS t(prodid, sumsales) QUALIFY QUANTILE(100,sumsales) >= 60; prodid sumsales Quantile --------- ----------- ----------- F 150000.00 60 A 170000.00 80 QUANTILE (n, colname) - where n (width) can be any integer 283

284 Varying Quantiles Show each product tertile based on total sales: SELECT t.prodid, t.sumsales, QUANTILE (3,sumsales ASC) FROM (SELECT a.prodid, SUM(a.sales) FROM salestbl a GROUP BY 1) AS t(prodid, sumsales); --------- ----------- ------------ B 65000.00 0 D 110000.00 0 C 115000.00 1 F 150000.00 1 A 170000.00 2 DESC means as quantile descends, column value descends. This is the default for any quantile function. Reported output will always show quantile ascending. SELECT t.prodid, t.sumsales, QUANTILE (3,sumsales DESC) FROM (SELECT a.prodid, SUM(a.sales) FROM salestbl a GROUP BY 1) AS t(prodid, sumsales); prodid sumsales Quantile --------- ----------- ----------- A 170000.00 0 F 150000.00 0 C 115000.00 1 D 110000.00 1 B 65000.00 2 ASC means as quantile descends, column value ascends. Lower quantiles get extra rows if distribution not uniform. 284

285 Ordering Quantiles Show all employees in lowest 25th percentile of salaries: SELECT employee_number, salary_amount, QUANTILE (100, salary_amount, employee_number) FROM employee QUALIFY QUANTILE(100, salary_amount) < 26; employee_number salary_amount Quantile ------------------------- -------------------- ----------- 1014 24500.00 03 1013 24500.00 00 1001 25525.00 07 1023 26500.00 11 1008 29250.00 15 1006 29450.00 19 1009 31000.00 23 Default for quantiles is column descends as quantile descends. Reporting output default is ascending quantile. If salary has a tie, employee # descends as quantile descends. Explicit ORDER BY may be used to reorder results. 285

286 SELECT employee_number, salary_amount, QUANTILE (100, salary_amount, employee_number ASC) FROM employee QUALIFY QUANTILE(100, salary_amount) < 26; employee_number salary_amount Quantile ------------------------- -------------------- ----------- 1013 24500.00 03 1014 24500.00 00 1001 25525.00 07 1023 26500.00 11 1008 29250.00 15 1006 29450.00 19 1009 31000.00 23 If salary has a tie, employee # ascends as quantile descends. 286

287 Aggregates and Quantiles Show all employee salaries in the top 25 % of the company: SELECT salary_amount, QUANTILE (100, salary_amount) FROM employee QUALIFY QUANTILE(100, salary_amount) >=75; salary_amount Quantile -------------------- ----------- 53625.00 76 54000.00 80 56500.00 84 57700.00 88 66000.00 92 100000.00 96 Get the sum of salaries of the top 25% of the company: SELECT SUM(salary_amount) FROM employee QUALIFY QUANTILE(100, salary_amount) >= 75; SELECT SUM(sals) FROM (SELECT salary_amount FROM employee QUALIFY QUANTILE(100, salary_amount) >= 75) temp(sals); Sum(sals) ---------------- 387825.00 (Error -- Can't mix stat functions with aggregates.) Correct approach -- use derived table. 287

288 Forecasting Using Linear Regression. Compute forecasted value for Y based on the previous n-1 rows. Y is called the dependent variable. Width (n) must be >=3 and <=4096. X is called the independent variable and is also the sort value. Both X and Y must be numeric columns which are not dates. SELECT X, Y, MLINREG(Y, 3, X) FROM linreg; MLINREG (Y, n, X) x y MLinReg ----------- ----------- -------------- 1 2 ? 2 4 ? 3 6 6 4 7 8 5 8 8 6 4 9 7 6 0 8 5 8 9 10 4 10 15 15 288

289 Examples SELECT X, Y, MLINREG(Y, 6, X) FROM linreg; x y MLinReg ----------- ----------- -------------- 1 2 ? 2 4 ? 3 6 6 4 7 8 5 8 9 6 4 10 7 6 6 8 5 5 9 10 4 10 15 8 What if you want to forecast based upon a date? First two rows are always null. Linearity of result depends on linearity of both variables. Sort default is ascending by independent column (X). ORDER BY can override sort defaults 289

290 Forecasting By Date Forecast using a linear regression the daily sales for items 10 and 11 for the first two weeks of 1998 using a width of 5: SELECT itemid,day_of_year,sales,MLINREG(sales,5,day_of_year) FROM jan_sales INNER JOIN Sys_calendar.calendar ON salesdate = calendar_date AND salesdate BETWEEN 980101 AND 980114 WHERE itemid IN (10,11) GROUP BY 1 ; Reset Use day_of_calendar instead of date as independent variable. GROUP BY clause used to restart regression on item change. GROUP BY clause also assigns major sort key - day is minor. 290

291 itemid day_of_year sales MLinReg ----------- ---------------- ----------- ------------- 10 1 150.00 ? 10 2 200.00 ? 10 3 250.00 250.00 10 4 350.00 300.00 10 5 550.00 400.00 10 6 150.00 625.00 10 7 200.00 300.00 10 8 100.00 100.00 10 9 150.00 -75.00 10 10 250.00 125.00 10 11 350.00 225.00 10 12 550.00 425.00 10 13 450.00 650.00 10 14 350.00 600.00 11 1 350.00 ? 11 2 100.00 ? 11 3 450.00 -150.00 11 4 550.00 400.00 11 5 250.00 600.00 11 6 350.00 475.00 11 7 200.00 250.00 11 8 150.00 100.00 11 9 250.00 125.00 11 10 450.00 150.00 11 11 550.00 475.00 11 12 250.00 700.00 11 13 350.00 400.00 11 14 350.00 250.00 291

292 Sampling SAMPLE function allows sampling of data based on either: an actual number of rows a percentage of a table Get a sampling of department numbers from 10 employees: SELECT department_number FROM employee SAMPLE 10; department_number ---------------------------- 401 403 401 301 401 403 402 401 292

293 Get a sampling of department numbers from 25% of employees: SELECT department_number FROM employee SAMPLE.25; department_number --------------------------- 403 401 402 301 501 403 6 Rows (out of 26) Note: Fractional results must be greater than.5 to generate an added row. 293

294 Sampling Distinct Values Get a sampling of 13 employees and count the distinct department numbers they represent: SELECT COUNT(DISTINCT department_number) FROM employee SAMPLE 13; *** Warning: 7473 Requested sample is larger than table rows. All rows returned Warning because attempts to return 13 rows. Only one row returned for count. Sample is based on entire employee table, not just 13 rows. Solution to problem -- use a derived table to get sample: SELECT COUNT(DISTINCT dept) FROM (SELECT department_number FROM employee SAMPLE 13) temp(dept); First try Count(Distinct(dept)) ---------------------------- 6 Second try Count(Distinct(dept)) ---------------------------- 5 Derived table produces sample of 13 rows. DISTINCT is applied against derived table. Subsequent attempts will return different samples. Different samples will produce different results. 294

295 Using SAMPLEID SAMPLEID assigns a sample-id to a specific sample set: SELECT department_number,sampleid FROM department SAMPLE.25,.25,.50 ORDER BY sampleid; department_number SampleId --------------------------- ------------- 301 1 403 1 302 2 401 2 100 3 402 3 201 3 600 3 295

296 SELECT department_number,sampleid FROM department SAMPLE 3, 5, 8 ORDER BY sampleid; department_number SampleId --------------------------- ------------- 302 1 301 1 403 1 100 2 402 2 401 2 201 2 600 2 501 3 *** Warning: 7473 Requested sample is larger than table rows. All rows returned 296

297 Module 23 Triggers 297

298 After completing this module, a student should see how to: Create, alter and drop triggers. Implement cascading and auditing triggers. Distinguish triggered statements from triggering statements 298

299 What is a Trigger? A Trigger may be defined as: One or more stored SQL statements associated with a table An event driven procedure attached to a table An object in a database, like tables, views and macros Any of the following SQL statements may be applied to triggers: Triggers may not be used in conjunction with: The Fastload utility The Multiload utility Updatable Cursors (Preprocessor environment) DELETE DATABASE DELETE USER Both cause all triggers to be dropped. Privileges are required to create and drop triggers. GRANT REVOKE CREATE DROP 299

300 Triggered and Triggering Statements A Triggering statement is an SQL statement which causes a trigger to fire. It is a ‘launching’ statement. Triggering statements may be any of the following: INSERT UPDATE DELETE INSERT SELECT A Triggered statement is an SQL statement which is executed as a result of the triggering statement execution. Triggered statements may be any of the following: INSERT UPDATE DELETE INSERT SELECT ABORT/ROLLBACK EXEC (macro) Triggered statements may never be any of the following: BEGIN TRANSACTION CHECKPOINT COMMIT END TRANSACTION SELECT 300

301 Defining a Trigger Create a trigger which: Fires when an department manager is changed. Updates the department employees to report to the new boss. CREATE TRIGGER MgrUpdate AFTER UPDATE OF (manager_employee_number) ON department REFERENCING OLD AS oldrow NEW AS newrow FOR EACH ROW WHEN (optional condition) (UPDATE employee SET manager_employee_number = newrow.manager_employee_number WHERE manager_employee_number = oldrow.manager_employee_number;); 301

302 Trigger Options CREATE TRIGGER MgrUpdate BEFORE UPDATE OF (manager_employee_number) ON department REFERENCING OLD AS oldrow NEW AS newrow FOR EACH ROW (UPDATE employee SET manager_employee_number = newrow.manager_employee_number WHERE manager_employee_number = oldrow.manager_employee_number;); Trigger Types ROW trigger: fires once for each row affected by triggering statement. references OLD and NEW rows of subject table. STATEMENT trigger: fires once per statement. references OLD_TABLE and NEW_TABLE subject tables. Triggered Action Times BEFORE AFTER INSTEAD OF 302

303 Multi-column updates BEFORE UPDATE OF (empno, deptno) ON employee (Both columns must be updated to fire trigger.) AFTER UPDATE ON employee (All columns must be updated to fire trigger.) 303

304 Conditional Triggers Create an audit trigger which inserts into a salary log a row for any employee receiving an increase of more than 10 %: CREATE TRIGGER raiseTrig AFTER UPDATE OF (salary_amount) ON employee ORDER 1 REFERENCING OLD AS oldrow NEW AS newrow FOR EACH ROW WHEN((newrow.salary_amount - oldrow.salary_amount)/ oldrow.salary_amount >.10) (INSERT INTO salary_log values (newrow.last_name, oldrow.salary_amount, newrow.salary_amount,date);); WHEN clause Like a WHERE clause for trigger execution. Returns True or False, (Null is considered false.) Can reference only those rows of subject table qualified by the triggering statement. ORDER clause Determines sequence of triggered event. May be between 1 and 32,767. Default value is 32,767. Triggers with same value fire randomly. To change ORDER clause, must REPLACE TRIGGER. ORDER is relevant only when: More than one trigger are defined on same table : Triggers have same Action time, Trigger event, Trigger type (Before/After) (Upd/Ins/Del) (Row/Stmt) 304

305 Cascading Triggers CREATE TABLE tab1 (a INT, b INT, c INT); CREATE TABLE tab2 (d INT, e INT, f INT); CREATE TABLE tab3 (g INT, h INT, i INT); CREATE TRIGGER trig1 AFTER INSERT ON tab1 REFERENCING NEW AS newrow FOR EACH ROW (INSERT INTO tab2 VALUES(newrow.a + 10, newrow.b + 10, newrow.c);); CREATE TRIGGER trig2 AFTER INSERT ON tab2 REFERENCING NEW AS newrow FOR EACH ROW (INSERT INTO tab3 VALUES(newrow.d + 100,newrow.e + 100,newrow.f);); INSERT INTO tab1 VALUES (1,2,3); SELECT * FROM tab1; a b c ----------- ----------- ----------- 1 2 3 SELECT * FROM tab2; d e f ----------- ------------ ----------- 11 12 3 305

306 SELECT * FROM tab3; g h i ----------- ------------ ----------- 111112 3 Cascading triggers are triggers which trigger other statements. May not modify their subject table. May cascade indefinitely. Cascading Trigger statements 306

307 Statement Triggers Create a trigger which will log any update of more than six rows to be run outside the production window: CREATE TRIGGER StageUpd INSTEAD OF UPDATE OF (salary_amount) ON employee REFERENCING OLD_TABLE AS oldtable NEW_TABLE AS newtable FOR EACH STATEMENT WHEN (TIME BETWEEN 80000 AND 170000 AND 6 < (SELECT COUNT(employee_number) FROM oldtable) ) (INSERT INTO StageTbl SELECT DATE, TIME, 'Update', employee_number, salary_amount FROM newtable; ); 307

308 Give a salary increase of 10% to those in the low 25 percentile: UPDATE employee SET salary_amount = salary_amount * 1.1 QUALIFY QUANTILE(100, salary_amount) < 26; (0 rows updated, 7 rows inserted) SELECT * FROM StageTbl; sdate stime dmltype sempno ssalamt ----------- ----------- ---------- ----------- ------------ 98/10/20 111338 Update 1009 34100.00 98/10/20 111338 Update 1013 26950.00 98/10/20 111338 Update 1014 26950.00 98/10/20 111338 Update 1006 32395.00 98/10/20 111338 Update 1001 28077.50 98/10/20 111338 Update 1023 29150.00 98/10/20 111338 Update 1008 32175.00 Statement triggers are less common than row triggers. WHEN clause may not refer to non-subject tables. 308

309 Referencing Rules Row Trigger: REFERENCING OLD AS oldrow NEW AS newrow FOR EACH ROW Statement Trigger: REFERENCING OLD_TABLE AS oldtable NEW_TABLE AS newtable FOR EACH STATEMENT OLD and NEW always reference rows as “correlations”. At most, one of each is specified per trigger. OLD_TABLE and NEW_TABLE reference tables as “aliases”. Only one OLD or OLD_TABLE permitted per trigger. Only one NEW or NEW_TABLE permitted per trigger. INSERTS may not use OLD_TABLE or OLD. DELETES may not use NEW_TABLE or NEW. 309

310 CREATE TRIGGER abc AFTER UPDATE ON Tbla REFERENCING OLD AS oldrow NEW AS newrow FOR EACH ROW WHEN ( newrow.a > oldrow.a ) INSERT INTO Tblx VALUES (newrow.a, oldrow.a); Both the WHEN clause and the Triggered statement may reference the subject table (Called an “outer reference”). Non-subject tables may be referenced in row triggers only. A triggered statement may never update the subject table. Only rows affected by the triggering statement are accessible. 310

311 Enabling Triggers Triggers may be enabled or disabled as needed. Disable prior to running Fastload or Multiload. ALTER TRIGGER StageUpd DISABLED;.sidetitles on.foldline on HELP TRIGGER StageUpd; Name StageUpd ActionTime I Event U Kind S Decimal Order Value 32,767 Enabled N Comment ? Comments may be added to a trigger. 311

312 COMMENT ON TRIGGER StageUpd ‘After Hours Updates’; Name StageUpd ActionTime I Event U Kind S Decimal Order Value 32,767 Enabled Y Comment After Hours Updates ALTER TRIGGER StageUpd ENABLED; Re-enable trigger. HELP TRIGGER StageUpd; 312

313 Triggers and Transactions All statements associated with a trigger are treated as one TXN. They are executed as a multi-statement request macro. Two triggered statements / one transaction: CREATE TRIGGER Trig1 AFTER INSERT ON Tab1 REFERENCING NEW AS newrow FOR EACH ROW BEGIN ATOMIC (INSERT INTO Tab2 VALUES(newrow.a + 10, newrow.b + 10, newrow.c); INSERT INTO Tab3 VALUES(newrow.a + 10, newrow.b + 10, newrow.c); ); END; 313

314 Alternate coding / same effect: CREATE TRIGGER Trig1 AFTER INSERT ON Tab1 REFERENCING NEW AS newrow FOR EACH ROW (INSERT INTO Tab2 VALUES(newrow.a + 10, newrow.b + 10, newrow.c); INSERT INTO Tab3 VALUES(newrow.a + 10, newrow.b + 10, newrow.c); ); When the triggering statement is launched, the macro becomes: INSERT INTO Tab1 INSERT INTO Tab2 INSERT INTO Tab3 Failure of any statement causes all to be rolled back 314

315 Multiple Triggers and Transactions If a triggering statement causes multiple triggers to fire, all statements across all triggers are treated as a single TXN. CREATE TRIGGER Trigger_2 BEFORE UPDATE OF (col_x) ON Tbl_x … FOR EACH ROW (DELETE FROM Tbl_y WHERE …………..; ); CREATE TRIGGER Trigger_3 AFTER UPDATE OF (col_x) ON Tbl_x … FOR EACH ROW (INSERT INTO Tbl_y WHERE …………..; ); When the triggering statement is launched, the macro becomes: DELETE FROM Tbl_y UPDATE Tbl_x SET col_x = ….. INSERT INTO Tbl_y Failure of any statement causes all to be rolled back. 315

316 Triggers, Transactions and ORDER The ORDER clause applies when two triggers have the same: Action time (AFTER) Trigger event (UPDATE) Trigger type (ROW) CREATE TRIGGER Trigger_4 : AFTER UPDATE OF (col_1) ON Tbl_1 ORDER 1 … FOR EACH ROW (DELETE FROM Tbl_2 WHERE …………..; ); CREATE TRIGGER Trigger_5 : AFTER UPDATE OF (col_1) ON Tbl_1 ORDER 2 … FOR EACH ROW (INSERT INTO Tbl_2 WHERE …………..; ); When the triggering statement is launched, the macro becomes: UPDATE Tbl_1 SET col_1 = ….. DELETE FROM Tbl_2 INSERT INTO Tbl_2 Failure of any statement causes all to be rolled back 316

317 Triggers and Referential Integrity Referential Integrity checks are made following each statement. Add the following RI constraint to the Job table: ALTER TABLE employee ADD CONSTRAINT job_1 FOREIGN KEY (job_code) REFERENCES job(job_code); Define a trigger which inserts into the job table any job code which is assigned to employees but isn’t found in the job table: CREATE TRIGGER trigger_6 : BEFORE UPDATE OF (job_code) ON employee REFERENCING OLD AS oldrow NEW AS newrow FOR EACH ROW WHEN (newrow.job_code NOT IN (SELECT job_code from job)) (INSERT INTO job VALUES (newrow.job_code, 'New Job',,,);) When the triggering statement is launched, the macro becomes: INSERT INTO job -- (only if job_code doesn’t already exist) UPDATE employee SET job_code = ……... Failure of any statement causes all statements to be rolled back If Trigger_6 were an AFTER trigger, the TXN would fail due to RI 317

318 Trigger Usage Guidelines Privileges needed to Create/Drop Triggers: CREATE/DROP TRIGGER on subject table or database SELECT for tables referenced in WHEN or Triggered Statements INS, UPD or DEL on the Triggered Statement(s) target table Priviliges needed to Execute Triggers: Whatever privilege is needed to execute triggering statement No EXEC-like privilege as with macros Trigger Limitations: CREATE TRIGGER text is limited to 8,192 bytes. Triggers may cascade indefinitely. A triggered action statement may not reference a subject table. WHEN Limitations: A WHEN clause may not reference the subject table directly. Aggregates are permitted in WHEN clause if in a subquery. Row level SELECTs are permitted in the WHEN clause only with statement triggers. DDL Limitations: A trigger must be dropped before dropping a referenced table. 318

319 Module 24 Global and Volatile Temporary Tables 319

320 After completing this module, a student should see how to: Create and populate both types of temp tables. Decide which type of temp table is appropriate for a given need. Use temp tables to enhance application performance. 320

321 Why Interim Tables? To allow SQL to perform operations that: Might not be possible against a normalized table, or May require multiple SQL statements For denormalizations such as: Summary tables Repeating groups For intermediate results which will be needed: Frequently, or On an on-going basis Create an interim table: CREATE TABLE Daily_Net_Trans (Account_Number INTEGER,Total_Trans_Amount DECIMAL(14,2)) UNIQUE PRIMARY INDEX (Account_Number); Populate it: INSERT INTO Daily_Net_Trans SELECT Account_Number,SUM(Trans_Amount) FROM Trans GROUP BY Account_Number; 321

322 Accessing An Interim Table SELECT * FROM Daily_Net_Trans WHERE Account_Number IN (20035223, 20024048, 20036699, 20045853) Account_Number Total_Trans_Amount ------------------------ ---------------------------- 20035223 -3280.00 20024048 -470.00 20036699 -870.00 20045853 -6910.00 Good news about interim tables Simpler SQL Doesn’t have to do aggregation May access Accounts based on Primary Index value Fast Response Bad news about interim tables Separate steps to create and populate table Requires extra perm space for temp table Table must be dropped when no longer needed Data dictionary access necessary for creation and dropping 322

323 Temp Table Choices Derived Tables (V2R2) Local to the query Incorporated into SQL query syntax Spool rows discarded when query finishes No data dictionary involvement Volatile Temporary Tables (V2R3) Local to a session Uses CREATE VOLATILE TABLE syntax Discarded automatically at session end No data dictionary involvement Global Temporary Tables (V2R3) Local to a session Uses CREATE GLOBAL TEMPORARY TABLE syntax Materialized instance of table discarded at session end Creates and keeps table definition in data dictionary 323

324 Derived Tables Revisited Get top three selling items across all stores: SELECT prodid, sumsales, RANK(sumsales) FROM (SELECT prodid, sum(sales) FROM salestbl GROUP BY 1) AS tmp(prodid, sumsales) QUALIFY RANK(sumsales) <= 3; prodid Sumsales Rank --------- --------------- ----------- A 170000.00 1 C 115000.00 2 D 110000.00 3 Derived table name is “tmp”. Derived column names are “prodid” and “sumsales”. Table is created in spool using the inner Select. SELECT statement is always in parenthesis following ‘FROM’. Derived tables are a good choice if: The table is required for this query but no others. The query will be run only one time with this data. 324

325 Volatile Temporary Tables Similar to derived tables: Materialized in spool No Data Dictionary access or transaction locks Table definition kept in cache Designed for optimal performance Different from derived tables: Is local to the session, not the query Can be used with multiple queries in the session Dropped manually anytime or automatically at session end Requires CREATE VOLATILE TABLE statement Example: CREATE VOLATILE TABLE vt_deptsal, LOG (deptno SMALLINT,avgsal DEC(9,2),maxsal DEC(9,2),minsal DEC(9,2),sumsal DEC(9,2),empcnt SMALLINT) ON COMMIT PRESERVE ROWS; CREATE Considerations: LOG indicates that a transaction journal is maintained. NO LOG allows for better performance. PRESERVE ROWS indicates keep table rows at TXN end. DELETE ROWS indicates delete all table rows at TXN end. Volatile tables do not survive a system restart. 325

326 Volatile Table Restrictions Restrictions: Up to 64 volatile tables are allowed on a single session. Each must have a unique name. Volatile tables are always qualified by the session’s userid. CREATE VOLATILE TABLE username.table1 (Explicit) CREATE VOLATILE TABLE table1 (Implicit) CREATE VOLATILE TABLE databasename.table1 (Error) Multiple sessions: Each session can use the same VT name (local to session). VT name cannot duplicate existing object name for this user – Perm or Temp table names – View names – Macro names – Trigger names FALLBACK: Electable but not often useful for VTs. VTs don’t survive a system reset. Options not permitted: Permanent Journaling Referential Integrity CHECK constraints Column compression Column default values Column titles Named indexes 326

327 Using Volatile Tables (1 of 2) CREATE VOLATILE TABLE vt_deptsal, LOG (deptno SMALLINT,avgsal DEC(9,2),maxsal DEC(9,2),minsal DEC(9,2),sumsal DEC(9,2),empcnt SMALLINT) ON COMMIT PRESERVE ROWS; INSERT INTO vt_deptsal SELECT dept,AVG(sal),MAX(sal),MIN(sal),SUM(sal),COUNT(emp) FROM emp GROUP BY 1; Show all employees who make the minimum salary in their department: SELECT emp, last, dept, sal FROM emp INNER JOIN vt_deptsal ON dept = deptno WHERE sal = minsal ORDER BY 3; 327

328 emp last dept sal ----------- -------------------- ----------- ---------------- 801 Trainer 100 100000.00 1025 Short 201 34700.00 1008 Kanieski 301 29250.00 1016 Rogers 302 56500.00 1013 Phillips 401 24500.00 1014 Crane 402 24500.00 1009 Lombardo 403 31000.00 1023 Rabbit 501 26500.00 328

329 Using Volatile Tables (2 of 2) Show all employees whose salary is more than their department average: SELECT emp, dept, sal, avgsal FROM emp INNER JOIN vt_deptsal ON dept = deptno WHERE sal > avgsal ORDER BY 2; emp dept sal avgsal ------------- ----------- ------------- ------------ 1021 201 38750.00 36725.00 1019 301 57700.00 38800.00 1010 401 46000.00 35082.14 1004 401 36300.00 35082.14 1002 401 43100.00 35082.14 1003 401 37850.00 35082.14 1011 402 52500.00 38500.00 1007 403 49700.00 38833.33 1020 403 39500.00 38833.33 1024 403 43700.00 38833.33 1015 501 53625.00 50031.25 1017 501 66000.00 50031.25 1018 501 54000.00 50031.25 All aggregates are already computed and available. VT is a small, easily scanned table. At session end, table will be dropped. 329

330 Getting Help on Volatile Tables. SET FOLDLINE ON.SET SIDETITLES ON HELP VOLATILE TABLE; (Returns info on all VT’s in the session) Session Id 3685 Table Name vt_deptsal Table Id 10C001000000 Protection N Creator Name PED Commit Option P Transaction Log Y SHOW TABLE vt_deptsal; CREATE SET VOLATILE TABLE PED1.vt_deptsal,NO FALLBACK, LOG ( deptno SMALLINT, avgsal DECIMAL(9,2), maxsal DECIMAL(9,2), minsal DECIMAL(9,2), sumsal DECIMAL(9,2), empcnt SMALLINT) PRIMARY INDEX ( deptno ) ON COMMIT PRESERVE ROWS; Note: HELP DATABASE command does not show VT’s. 330

331 Limitations on Volatile Tables The following commands are not applicable to VT’s: COLLECT/DROP/HELP STATISTICS CREATE/DROP INDEX ALTER TABLE GRANT/REVOKE privileges DELETE DATABASE/USER (does not drop VT’s) VT’s may not: Use ACCESS LOGGING. Be RENAMEd. Be loaded with Multiload or Fastload utilities. VT’s may be referenced in views and macros: CREATE MACRO vt1 AS (SELECT * FROM vt_deptsal;); Session A EXEC vt1 Session B EXEC vt1 Each session has its own materialized instance of vt_deptsal. Each session may return different results. VT’s may be dropped before session ends: DROP TABLE vt_deptsal; 331

332 Global Temporary Tables Global Temporary Tables: Are created using CREATE GLOBAL TEMPORARY command. Require a base definition which is stored in the DD. Are materialized by first SQL DML statement to access table. Global Temporary Tables are different from Volatile Tables: Base definition is permanent and kept in DD. Requires DML privileges necessary to materialize the table. Space is charged against an allocation of “temporary space”. User can materialize up to 32 global tables per session. Tables can survive a system restart. Global Temporary Tables are similar to Volatile Tables: Each instance of global temp table is local to a session. Materialized tables are dropped automatically at session end. Have LOG and ON COMMIT PRESERVE/DELETE options. Materialized table contents aren’t sharable with other sessions. NOTE Volatile temporary tables are referred to as “Volatile Tables”. Global temporary tables are referred to as “Temporary Tables”. 332

333 Creating Temporary Tables CREATE GLOBAL TEMPORARY TABLE gt_deptsal (deptno SMALLINT,avgsal DEC(9,2),maxsal DEC(9,2),minsal DEC(9,2),sumsal DEC(9,2),empcnt SMALLINT); Base table definition stored in DD/D Default is ON COMMIT DELETE ROWS ALTER TABLE gt_deptsal, ON COMMIT PRESERVE ROWS; Table is now materialized INSERT INTO gt_deptsal SELECT dept,AVG(sal),MAX(sal),MIN(sal),SUM(sal),COUNT(emp) FROM emp GROUP BY 1; Row is inserted in DBC.Temptables DELETE FROM gt_deptsal; Table remains materialized until it is dropped 333

334 Space Allocations CREATE USER john AS PERM = 5000000, PASSWORD = lucky, SPOOL = 5000000, TEMPORARY = 2000000; PERM TEMP SPOOL DD/D Perm tables Temporary Temporary space, like perm space, survives a system reset. Like spool space, it is deallocated at the session end. If unspecified, default is set to max of immediate owner. 334

335 CREATE SET TABLE dbc.temptables,FALLBACK, NO BEFORE JOURNAL, NO AFTER JOURNAL ( HostNo SMALLINT FORMAT '---,--9' NOT NULL, SessionNo INTEGER FORMAT '--,---,---,--9' NOT NULL, TableId BYTE(6) NOT NULL, BaseDbId BYTE(4) NOT NULL, BaseTableId BYTE(6) NOT NULL, AccountDbId BYTE(4) NOT NULL, StatisticsCnt SMALLINT FORMAT '---,--9' NOT NULL) PRIMARY INDEX ( HostNo,SessionNo ); New dictionary table DBC.Temptables One row for each materialized instance of any temporary table 335

336 Getting Help on Temporary Tables HELP DATABASE ped; Table/View/Macro Kind Comment ------------------------ ----- ---------------- employee T ? empsamp T ? exceed_10_pcent T ? gt_deptsal T ? HELP TABLE gt_deptsal; Column Name Type Comment -------------------------- ---- -------- deptno I2 ? avgsal D ? maxsal D ? Minsal D ? empcnt I2 ? SHOW TABLE gt_deptsal; CREATE SET GLOBAL TEMPORARY TABLE PED.gt_deptsal,NO FALLBACK, LOG ( deptno SMALLINT, avgsal DECIMAL(9,2), maxsal DECIMAL(9,2), minsal DECIMAL(9,2), sumsal DECIMAL(9,2), empcnt SMALLINT) PRIMARY INDEX ( deptno ) ON COMMIT PRESERVE ROWS; 336

337 Using Temporary Tables Show all employees who make the maximum salary in their dept: SELECT emp, last, dept, sal FROM emp INNER JOIN gt_deptsal ON dept = deptno WHERE sal = maxsal ORDER BY 3; emp last dept sal ----------- -------------------- ----------- -------------- 801 Trainer 100 100000.00 1021 Morrissey 201 38750.00 1019 Kubic 301 57700.00 1016 Rogers 302 56500.00 1010 Rogers 401 46000.00 1011 Daly 402 52500.00 1007 Villegas 403 49700.00 1017 Runyon 501 66000.00 337

338 Show employees who are in a department of less than 3 people: SELECT emp, last, dept, empcnt FROM emp INNER JOIN gt_deptsal ON dept = deptno WHERE empcnt < 3; emp last dept empcnt ----------- -------------------- ----------- ---------- 801 Trainer 100 1 1014 Crane 402 2 1025 Short 201 2 1011 Daly 402 2 1021 Morrissey 201 2 1016 Rogers 302 1 338

339 Temporary Tables and DDL (1 of 2) TEMPORARY keyword in command denotes table instance only; otherwise applies to base definition and instance TEMPORARY keyword used for temporary tables only TEMPORARY and ALL are mutually exclusive Dropping tables: DROP TEMPORARY TABLE gt_deptsal; Drops local instance of table only. DROP TABLE gt_deptsal; Drops base definition and local instance if present. Fails is there are other instances of the table in the system. DROP TABLE gt_deptsal ALL; Drops base and all instances. Fails if any instance is in an active transaction. Deleting Databases/Users: DELETE DATABASE db1; Deletes all objects in database, including temporary tables. Fails if any instances of temporary table are materialized. DELETE DATABASE db1 ALL; Deletes all objects, including materialized temporary tables. Showing table definitions: SHOW TABLE gt_deptsal; Shows definition of base table. SHOW TEMPORARY TABLE gt_deptsal; Shows definition of materialized instance. 339

340 Temporary Tables and DDL (2 of 2) Altering tables: ALTER TABLE gt_deptsal, ON COMMIT PRESERVE ROWS; Also used to alter LOG option. Changes base definition of table. Fails if there are any materialized instances. Views and macros CREATE MACRO gt1 AS (SELECT * FROM gt_deptsal;); Macros and views must reference base table definition. Execution of macro or view can materialize table. Granting/Revoking privileges GRANT INSERT, SELECT ON gt_deptsal TO user1; Applies to base definition only. Appropriate DML rights needed to materialize table. DML rights needed on base or on containing database. Once table is materialized, no rights are checked. HELP on indexes: HELP TEMPORARY INDEX gt_deptsal; Shows indexes defined on materialized table. Without TEMPORARY, shows indexes on base. HELP on statistics: HELP TEMPORARY STATISTICS gt_deptsal; Shows statistics defined on materialized table. Without TEMPORARY, shows statistics defined on base. 340

341 Creating Secondary Indexes Secondary indexes may be added to a temporary table. They may be added either to the base or to an instance. CREATE INDEX (empcnt) ON gt_deptsal; Creates index on base table definition. Fails if an instance of the table already exists. Subsequent instances of table will have this index. Can never use a “named” index with temporary tables. SHOW TABLE gt_deptsal; CREATE SET GLOBAL TEMPORARY TABLE PED.gt_deptsal,NO FALLBACK, LOG ( deptno SMALLINT, avgsal DECIMAL(9,2),maxsal DECIMAL(9,2), minsal DECIMAL(9,2), sumsal DECIMAL(9,2), empcnt SMALLINT) PRIMARY INDEX ( deptno ) INDEX ( empcnt ) ON COMMIT PRESERVE ROWS; CREATE INDEX (empcnt) ON TEMPORARY gt_deptsal; Creates index on materialized instance. Fails if index already defined as part of base table. 341

342 SHOW TEMPORARY TABLE gt_deptsal; CREATE SET GLOBAL TEMPORARY TABLE PED.gt_deptsal,NO FALLBACK, LOG( deptno SMALLINT, avgsal DECIMAL(9,2),maxsal DECIMAL(9,2), minsal DECIMAL(9,2), sumsal DECIMAL(9,2), empcnt SMALLINT) PRIMARY INDEX ( deptno ) INDEX ( empcnt ) ON COMMIT PRESERVE ROWS; 342

343 Dropping Secondary Indexes Secondary indexes may be dropped from a temporary table. They may be dropped either from the base or from an instance. DROP INDEX (empcnt) ON TEMPORARY gt_deptsal; Drops index on materialized instance. HELP TEMPORARY INDEX gt_deptsal; Note: Base table keeps index definition. Unique? Secondary? Column Names ----------- ---------------- -------------------- N P deptno HELP INDEX gt_deptsal; Primary or Unique? Secondary? Column Names ----------- ---------------- -------------------- N P deptno N S empcnt DROP INDEX (empcnt) ON gt_deptsal; Drops index on base table definition. Fails if an instance of the table already exists. 343

344 Collecting Statistics COLLECT STATISTICS May be done on a base table or a materialized instance. Done on a base table; defines which columns will be collected. Done on an instance; actually collects and stores statistics. COLLECT STATISTICS ON gt_deptsal index (deptno); Defines index to be collected. COLLECT STATISTICS ON gt_deptsal column avgsal; Defines column to be collected. HELP STATISTICS gt_deptsal; Date Time Unique Values Column Names ------------ ------------ -------------------- ----------------- 98/09/11 13:38:37 0 deptno 98/09/11 13:39:01 0 avgsal INSERT INTO gt_deptsal SELECT dept,AVG(sal),MAX(sal),MIN(sal),SUM(sal),COUNT(emp) FROM emp GROUP BY 1; 344

345 COLLECT STATISTICS ON gt_deptsal; Fails; not allowed when table is materialized. There are no statistics to collect on base table. COLLECT STATISTICS ON temporary gt_deptsal; Collects statistics on the instance. HELP TEMPORARY STATISTICS gt_deptsal; Date Time Unique Values Column Names ------------ ------------ -------------------- ----------------- 98/09/11 13:46:08 8 deptno 98/09/11 13:46:08 8 avgsal 345

346 Dropping Statistics DROP STATISTICS May be done on a base table or a materialized instance. Done on a base table; drops column(s) from base definition. Done on an instance; drops statistics from the instance. DROP STATISTICS ON gt_deptsal; Fails; not allowed when table is materialized. DROP STATISTICS ON TEMPORARY gt_deptsal column avgsal; Drops stats on columns avgsal for table instance. HELP TEMPORARY STATISTICS gt_deptsal; Date Time Unique Values Column Names ------------ ------------ -------------------- --------------------- 98/09/11 13:46:08 8 deptno DROP STATISTICS ON TEMPORARY gt_deptsal; Drop all statistics for table instance. HELP TEMPORARY STATISTICS gt_deptsal; No statistics returned. All statistics have been dropped from the instance. HELP STATISTICS gt_deptsal; Date Time Unique Values Column Names ------------ ------------ -------------------- ----------------- 98/09/11 13:38:37 0 deptno 98/09/11 13:39:01 0 avgsal COLLECT STATISTICS ON TEMPORARY gt_deptsal; Fails; no statistics are defined for the instance. 346

347 Module 25 ANSI Time and Dates 347

348 After completing this module, a student should see how to: Perform queries using ANSI compliant Time and Date representations. Use Interval data types for date/time arithmetic. Extract appropriate date/time based information. Create date/time based literals. 348

349 SET SESSION DATEFORM = ANSIDATE; /* ANSI Default format */ Select current_date; Current Date ------------------ 1998-11-05 Select date; Date ------------------ 1998-11-05 SET SESSION DATEFORM = INTEGERDATE; /* Teradata default */ Select current_date; Current Date ----------------- 98/11/05 Select date; Date ----------- 98/11/05 Default Date Formatting Select DATE; /* Traditional Teradata current date selection */ Date ------------ 98/11/05 Select CURRENT_DATE; /* ANSI standard current date selection */ Date ----------- 98/11/05 Controls default display of selected dates. Controls import and export of dates as character strings. Is switchable during session. 349

350 Setting Date Defaults System Level (DBSCONTROL record) MODIFY GENERAL 14 = 0 /* INTEGERDATE (YY/MM/DD) */ MODIFY GENERAL 14 = 1 /* ANSIDATE (YYYY-MM-DD) */ USER level CREATE USER ped …….. DATEFORM = ANSIDATE = INTEGERDATE SESSION level SET SESSION DATEFORM = ANSIDATE= INTEGERDATE Importing an ANSI date to a Teradata date column: CREATE TABLE tbla (tbldate DATE); SET SESSION DATEFORM = ANSIDATE; USING newdate (CHAR(10)) INSERT INTO tbla ( :newdate); Imports a character string of 'yyyy-dd-mm' and converts to date 350

351 Interval Data Types (Year-Month) Interval data types represent a displacement between two points in time. Intervals are stored as one or multiple numeric fields combined into a single data type. There are two general categories of INTERVAL data types: Year-Month Intervals: INTERVAL YEAR(n) -9999 to +9999 years (n=1-4) INTERVAL MONTH(n) -9999 to +9999 months INTERVAL YEAR(n) TO MONTH -9999 to 9999 years and 0 -12 months Examples of Year-Month Interval Literals: INTERVAL -’32’ YEAR (-32 years) INTERVAL ‘9’ MONTH (+ 9 months) INTERVAL ‘5-08’ YEAR TO MONTH (+5 years, 8 months) Sign is outside of quotestring. Plus (+) is default, represented by a blank. Explicit + generates error. Default value for n = 2. Precision (n) is not specified with literals. Day Interval: INTERVAL DAY(n) -9999 to +9999 days, (n=1-4) Examples of Day Interval Literal: INTERVAL -‘365’ DAY (-365 days) 351

352 Interval Literals in Date Arithmetic Date + Interval = Date Interval + Interval = Interval Date - Date = Interval Interval * / n = Interval SET SESSION DATEFORM = ANSIDATE; Show today’s date: SELECT CURRENT_DATE; 1998-11-06 Show the date 2 days ago: SELECT CURRENT_DATE - INTERVAL '2' DAY; 1999-01-24 Show the date in 3 years: SELECT CURRENT_DATE + INTERVAL '3' YEAR; 2001-11-06 Show the date in 3 months ago: SELECT CURRENT_DATE + INTERVAL -'3' MONTH; 1995-08-06 Add 5 years and 10 months to 2 years and 3 months: SELECT (INTERVAL '5-10' YEAR TO MONTH) + (INTERVAL '2-03' YEAR TO MONTH); 8-01 352

353 Date Literals Date literals are always represented by the format: DATE “YYYY-MM-DD” Add 2 months to December 29, 1998: SELECT (DATE '1995-12-29' + INTERVAL '2' MONTH); 1996-02-29 Add 2 months to December 29, 1998: SELECT (DATE '1998-12-29' + INTERVAL '2' MONTH); *** Failure 2665 Invalid date. Add 2 years and 3 months to July 15, 1999: SELECT DATE '1999-07-15' + INTERVAL '2-03' YEAR TO MONTH; 2001-10-15 Add 2 months to December 31, 1995: SELECT ADD_MONTHS(DATE '1995-12-31',2); 1996-02-29 353

354 Date Subtraction Yields Days Date - Date = Interval or Integer How many days are between Jan. 1 and Mar 1 of 1999? SELECT (DATE '1999-03-01' - DATE '1999-01-01') DAY; 59 Result is an INTERVAL DAY(2) data type. May be used in INTERVAL calculation. How many days are between Jan. 1, 1996 and Mar 1,1999? SELECT DATE '1999-03-01' - DATE '1996-01-01'; 1155 Result is an INTERVAL DAY(4) data type. How many days are between Jan. 1, 1996 and Mar 1,1999? SELECT (DATE '1999-03-01' - DATE '1996-01-01’) DAY; *** Failure 7453 Interval Field Overflow. How many days are between Jan. 1, 1996 and Mar 1,1999? SELECT (DATE '1999-03-01' - DATE '1996-01-01’) DAY(4); 1155 Result is an integer representing # days. 354

355 Date Subtraction Yields Years and Months How many days are between Jan. 1, 1898 and Mar 1,1999? SELECT (DATE '1999-03-01' - DATE '1899-01-01’) YEAR TO MONTH; *** Failure 7453 Interval Field Overflow. How many year/months are between Jan 1 1898 and Mar 1 1999? SELECT (DATE '1999-03-01' - DATE '1899-01-01’) YEAR(3) TO MONTH; 100-02 How many year/months are between Jan 1 1898 and Mar 1 1999? SELECT (DATE '1999-03-01' - DATE '1899-01-01’) MONTH; *** Failure 7453 Interval field overflow. How many months are between Jan 1, 1898 and Mar 1, 1999? SELECT (DATE '1999-03-01' - DATE '1899-01-01’) MONTH(4); 1202 How many months are between Jan 1, 1898 and Mar 1, 1999? SELECT DATE '1999-03-01' - DATE '1898-01-01'; 36948 Result is an integer representing # days Cannot be represented as INTERVAL 355

356 Extracting From Date EXTRACT YEAR MONTH DAY FROM (DATE) Extract the year from Dec. 15, 1999: SELECT EXTRACT (YEAR FROM DATE '1999-12-15'); 1999 Extract the year 20 days following Dec. 15, 1999: SELECT DATE '1999-12-15' + INTERVAL '20' DAY; 2000-01-04 What is the date 20 days after Dec. 15, 1999? SELECT EXTRACT (YEAR FROM (DATE '1999-12-15' + INTERVAL '20' DAY)); 2000 Extract the month 20 days following Dec. 15, 1999: SELECT EXTRACT (MONTH FROM (DATE '1999-12-15' + INTERVAL '20' DAY)); 1 Extract the day 20 days following Dec. 15, 1999 : SELECT EXTRACT (DAY FROM (DATE '1999-12-15' + INTERVAL '20' DAY)); 4 356

357 ANSI Time Teradata TIME (traditional) A selectable system column - SELECT TIME Not a data type An integer without clock intelligence (hhmmss) ANSI TIME A data type supported by Teradata with clock intelligence Three fields stored in one 6 byte column Up to six digits precision TIME(n) - Where n = 0-6 (default is 6) HH:MM:SS.nnnnnn HH - stored as byteint (1 byte) MM - stored as byteint (1 byte) SS - stored as dec(8,6) (4 bytes) Time representation (Character conversion requirement) TIME (0) - 11:37:58 CHAR(8) TIME (6) - 11:37:58.213000 CHAR(15) CREATE TABLE tbla (tbltime TIME); INSERT INTO tbla (CURRENT_TIME); SELECT * FROM tbla; tbltime ---------------------- 11:33:13.480000 Teradata DATE Review A selectable system column - SELECT DATE A column date type - CAST(990101 as DATE) Really three fields stored in one 32 bit integer Calendar intelligence - permits mathematical operation 357

358 Simple Day-Time Intervals Interval data types represent a displacement between two points in time. There are two general categories of INTERVAL data types: Year-Month Intervals Day-Time Intervals Simple Day-Time Intervals: INTERVAL DAY(n) -9999 to +9999 days, (n=1-4) INTERVAL HOUR(n) -9999 to +9999 hours INTERVAL MINUTE(n) -9999 to +9999 minutes INTERVAL SECOND(n,m) 9999.999999 seconds Examples of Simple Day-Time Interval Literals: INTERVAL ’320’ DAY (320 days) INTERVAL -‘9’ HOUR (- 9 hours) INTERVAL ‘700’ MINUTE (700 minutes) INTERVAL ‘1375.904508’ SECOND (1375.904508 seconds) Note: Default values n=2, m=6. 358

359 Complex Day-Time Intervals Complex day-time intervals are combinations of simple intervals. Examples of Complex Day-Time Interval Literals: INTERVAL ’25 09’ DAY TO HOUR (25 days, 9 hours) INTERVAL -‘9 13:36’ DAY TO MINUTE (- 9 days,13 hrs,36min) INTERVAL ‘25 13:36:15.5’ DAY TO SECOND (25 days,13 hrs,36min,15.5 secs) INTERVAL ‘13:36’ HOUR TO MINUTE (13 hrs,36 min) INTERVAL ‘13:36:15.5’ HOUR TO SECOND (13 hrs,36min,15.5 secs) INTERVAL ‘36:15.5’ MINUTE TO SECOND (36 min,15.5 secs) When an interval literal is specified in an SQL statement, the parser can determine the exact data type: I.e., INTERVAL ‘1375.90’ SECOND is SECOND(4,2) 359

360 Interval Literals in Time Arithmetic Add 3 days, 5 hrs, 23 mins to 2 days, 3 hrs, 23 mins: SELECT INTERVAL '03 05:23' DAY TO MINUTE + INTERVAL '02 03:23' DAY TO MINUTE; 5 08:46 Add 43 mins to 5 hrs and 23 mins: SELECT INTERVAL '05:23' HOUR TO MINUTE + INTERVAL '43' MINUTE; 6:06 24:06.04 Add 30 mins 49 secs to 23 hrs, 35 mins, 55 secs: SELECT INTERVAL '23:35.55' HOUR TO SECOND + INTERVAL '30:49' MINUTE TO SECOND; INTERVAL _+ INTERVAL = INTERVAL Add 30.49 secs to 23 hrs: SELECT INTERVAL '23' HOUR + INTERVAL '30.49' SECOND; 23:00:30.49 360

361 Time Literals Assuming the current time is 09:30:22, what time will it be in one hour and 20 minutes? SELECT TIME '09:30:22' + INTERVAL '01:20' HOUR TO MINUTE; 10:50:22 What time was it one hour and 20 minutes and 10 seconds ago? SELECT TIME '09:30:22' - INTERVAL '01:20:10' HOUR TO SECOND; 08:10:12 Time literals are represented by the format: TIME ‘HH:MM:SS.nnnnnn’ Redo the previous example using TIME(2) for current time: SELECT TIME '09:30:22.45' - INTERVAL '01:20:10' HOUR TO SECOND; 08:10:12.45 Time literal is of type TIME(2) Time interval is of type HOUR TO SECOND(0) Result is TIME(2) Redo the same example with an HOUR TO SECOND(2) interval: SELECT TIME '09:30:22' - INTERVAL '01:20:10.45' HOUR TO SECOND; 08:10:11 Time literal is of type TIME(0) Time interval is of type HOUR TO SECOND(2) Result is TIME(0) - subtract first, round result 361

362 Time Subtraction How many full hours elapse between 8 AM and 10:35:40 AM? SELECT (TIME '10:35:40' - TIME '08:00:00') HOUR; 2 How many minutes elapse between 8 AM and 10:35:40 AM? SELECT (TIME '10:35:40' - TIME '08:00:00') MINUTE; *** FAILURE 7453 INTERVAL FIELD OVERFLOW. How many minutes elapse between 8 AM and 10:35:40 AM? SELECT (TIME '10:35:40' - TIME '08:00:00') MINUTE(3); 155 How many seconds elapse between 8 AM and 10:35:40 AM? SELECT (TIME '10:35:40' - TIME '08:00:00') SECOND(4); 9340.000000 TIME - TIME = HOUR HOUR TO MINUTE HOUR TO SECOND MINUTE MINUTE TO SECOND SECOND 362

363 Day-Time Interval Castings Convert 3 hours, 45 minutes to hours: SELECT CAST((INTERVAL '3:45' HOUR TO MINUTE) AS INTERVAL HOUR); 3 Convert 3 hours, 45 minutes to minutes: SELECT CAST((INTERVAL '3:45' HOUR TO MINUTE) AS INTERVAL MINUTE(3)); 225 Convert 50 hours, 45 minutes to days, hours and minutes: SELECT CAST((INTERVAL '50:45' HOUR TO MINUTE) AS INTERVAL DAY TO MINUTE); 2 02:45 Reverse the previous conversion: SELECT CAST((INTERVAL '2 02:45' DAY TO MINUTE) AS INTERVAL HOUR TO MINUTE); 50:45 363

364 Day-Time Interval Castings and Calculations Convert 2 hours to seconds with 6-point precision: SELECT CAST((INTERVAL '2' HOUR) AS INTERVAL SECOND(4)); 7200.000000 Convert 2 hours to seconds without precision: SELECT CAST((INTERVAL '2' HOUR) AS INTERVAL SECOND(4,0)); 7200 Interval Calculations Compute half of the interval 3 days and 7 hours: SELECT INTERVAL '3 07' DAY TO HOUR/2; 1 15 Triple the interval 3 days, 2 hours and 20 minutes: SELECT INTERVAL '03 02:20' DAY TO MINUTE*3; 9 07:00 364

365 Extracting From Time Extract the hour portion from the time 09:45:20: SELECT TIME '09:45:20‘ + INTERVAL '20:45' MINUTE TO SECOND; 10:06:05 Extract the hours portion from the new time: SELECT EXTRACT (HOUR FROM (TIME '09:45:20‘ + INTERVAL '20:45' MINUTE TO SECOND)); 10 Add 20 minutes and 45 seconds to the time 09:45:20: SELECT EXTRACT (MINUTE FROM (TIME '09:45:20‘ + INTERVAL '20:45' MINUTE TO SECOND)); 6 Extract the minutes portion from the new time: SELECT EXTRACT (SECOND FROM (TIME '09:45:20‘ + INTERVAL '20:45' MINUTE TO SECOND)); 5 Extract the seconds portion from the new time: SELECT EXTRACT (HOUR FROM (TIME '09:45:20')); 9 365

366 Module 26 ANSI Timestamps and Time Zones 366

367 Upon completion of this module, the student should see how to: Perform queries using ANSI compliant Timestamp and Time With Zone representations. Use Timestamps for time sequenced processing. Use Zones for geographic location based processing. Extract time or date information from a timestamp. 367

368 ANSI Timestamp Timestamp combines date and time into a single column. TIMESTAMP(n) - Where n=(0-6) Consists of 6 fields of information YEAR,MONTH,DAY,HOUR,MINUTE,SECOND Internal format is DATE(4 bytes) + TIME(6 bytes) = 10 bytes Timestamp representation Character conversion TIMESTAMP(0) 1998-12-07 11:37:58 CHAR(19) TIMESTAMP(6) 1998-12-07 11:37:58.213000 CHAR(26) CREATE TABLE tblb (tmstampb TIMESTAMP); INSERT INTO tblb (CURRENT_TIMESTAMP); SELECT * FROM tblb; tmstampb --------------------------------------- 1998-11-06 13:48:38.580000 368

369 Timestamp Literals Timestamp literals are represented by the format: TIMESTAMP “YYYY-MM-DD HH:MM:SS.nnnnnn” Subtract 2 yrs and 6 mos from the designated timestamp: SELECT TIMESTAMP '1999-10-01 09:30:22‘ INTERVAL '01:20:10' HOUR TO SECOND; Subtract 1 hr, 20 mins and 10 secs from designated timestamp: SELECT TIMESTAMP '1999-10-20 09:30:22‘ + INTERVAL '08 10:15' DAY TO MINUTE; 1999-10-01 08:10:12 Add 8 days, 10 hrs, 15 mins to the designated timestamp: SELECT TIMESTAMP '1999-10-01 09:30:22‘ - INTERVAL '2-06' YEAR TO MONTH; 1997-04-01 09:30:22 1999-10-28 19:45:22 Subtract 1 hr, 20 min, 10.45 sec from the designated timestamp: SELECT (TIMESTAMP '1999-10-01 09:30:22' - INTERVAL '01:20:10.45‘ HOUR TO SECOND); 1999-10-01 08:10:11 Timestamp is TIMESTAMP(0) Interval is HOUR TO SECOND(2) Result is TIMESTAMP(0) Result may be re-cast if needed 369

370 Timestamp Subtraction Given the following two timestamps, calculate the difference between them as directed: In months? In years? In days? In days, hours, minutes and seconds? SELECT (TIMESTAMP '1999-10-20 10:25:40' - TIMESTAMP '1998-09-19 08:20:00') MONTH; 13 SELECT (TIMESTAMP '1999-10-20 10:25:40' - TIMESTAMP '1998-09-19 08:20:00') YEAR; 1 SELECT (TIMESTAMP '1999-10-20 10:25:40' - TIMESTAMP '1998-09-19 08:20:00') DAY(3); 396 SELECT (TIMESTAMP '1999-10-20 10:25:40' - TIMESTAMP '1998-09-19 08:20:00') DAY(3) TO SECOND; 396 02:05:40.000000 370

371 Timestamp Casting : TIMESTAMP may be CAST as: DATE TIME(n) TIMESTAMP(n) Casting which truncates precision is not permitted Cast the given timestamp as a Date SELECT CAST(TIMESTAMP '1999-10-01 09:30:22' AS DATE); 99/10/01 09:30:22.00 Cast the given timestamp as a Time: SELECT CAST(TIMESTAMP '1999-10-01 09:30:22' AS TIME(2)); Subtract the given interval and cast the result as TIMESTAMP(2): SELECT CAST((TIMESTAMP '1999-10-01 09:30:22' – INTERVAL '01:20:10.45' HOUR TO SECOND) AS TIMESTAMP(2)); 1999-10-01 08:10:11.55 Reduce the precision of the timestamp to two places: SELECT CAST((TIMESTAMP '1999-10-01 09:30:22.000000') AS TIMESTAMP(2)); *** Failure 7454 DateTime field overflow. 371

372 Time Zones CURRENT_TIME & CURRENT_TIMESTAMP both return time zone SELECT CURRENT_TIME; Current Time --------------------- 16:29:30+00:00 SELECT CURRENT_TIMESTAMP; Current TimeStamp ------------------------------------------------ 1998-11-16 16:30:02.070000+00:00 Time zones may be relative to: Greenwich Meridian Time (GMT) Your Local Time Zone Any Time Zone you choose LA London Hong Kong 00:00 (GMT) -08:00 +08:00 London Hong LA Kong 00:00 +08:00 (GMT) +16:00 Relative to GMT Relative to LA 372

373 Data Types With Time Zone TIME(n) WITH TIME ZONE Consists of TIME(n) + two additional fields (6+2 = 8 bytes) TIMEZONE_HOUR (byteint, -12 to +13) TIMEZONE_MINUTE (byteint, 00 to 59) Literal time representations Data Type TIME ‘11:37:58’ TIME(0) TIME ‘11:37:58-08:00’ TIME(0) WITH TIME ZONE TIME ‘11:37:58.213000+09:30’ TIME WITH TIME ZONE TIMESTAMP(n) WITH TIME ZONE Consists of TIMESTAMP(n) + same two additional fields (10+2 = 12) Literal time representations Data Type TIMESTAMP ‘1999-10-01 11:37:58’ TIMESTAMP(0) TIMESTAMP TIMESTAMP(0) ‘1999-10-01 11:37:58-08:00’ WITH TIME ZONE TIMESTAMP ‘1999-10-01 11:37:58.213000+09:30’ WITH TIME ZONE UTC = 00:00 Universal Coordinated Time Also known as GMT Default if Time Zone unspecified EST = -05:00 Eastern Standard Time (5 hours earlier) EDT = -04:00 Eastern Daylight Time PST = -08:00 Pacific Standard Time Relative Time Zones 373

374 Setting Time Zones MODIFY GENERAL 16 = n /* Hour, n= -12 to +13 */ MODIFY GENERAL 17 = n /* Minutes, n = -59 to +59 */ System Level (DBSCONTROL record) CREATE USER ped …….. TIME ZONE = LOCAL /* use system level */ = NULL /* no default, set at system or session level at logon*/ = ‘08:00’ /* explicit setting*/ = -‘04:30’ /* explicit setting*/ USER level SET TIME ZONE LOCAL /* switch from session level to system level */ SET TIME ZONE USER /* switch from session level to user level */ SET TIME ZONE INTERVAL ‘05:00’ HOUR TO MINUTE /* explicit setting */ SESSION level There are three levels at which the default time zone may be set: 374

375 Working With Zones (1 of 4) User Name PED Account Name DBC Logon Date 98/11/17 Logon Time 10:33:44 Current DataBase PED Collation ASCII Character Set ASCII Transaction Semantics Teradata Current DateForm IntegerDate Session Time Zone 00:00 HELP SESSION; (System level time zone is 00:00) CREATE TABLE zone_test (loc_id CHAR(3), timestmp_with_zone TIMESTAMP(0) WITH TIME ZONE); INSERT INTO zone_test (’GMT',TIMESTAMP '1999-04-15 10:30:00'); (Note: zone is defaulted) SELECT loc_id, timestmp_with_zone FROM zone_test; loc_Id timestmp_with_zone ----------- -------------------------------------- GMT 1999-04-15 10:30:00+00:00 (Note: Zone is explicit) SELECT loc_id, CAST(timestmp_with_zone AS TIMESTAMP(0)) FROM zone_test; loc_Id timestmp_with_zone ------------ ----------------------------- GMT 1999-04-15 10:30:00 (Note: Zone is implicit) 375

376 Working With Zones (2 of 4) SET TIME ZONE INTERVAL -'08:00' HOUR TO MINUTE; Reset time zone default to be local to PST User Name PED Account Name DBC Logon Date 98/11/17 Logon Time 10:33:44 Current DataBase PED Collation ASCII Character Set ASCII Transaction Semantics Teradata Current DateForm IntegerDate Session Time Zone -08:00 HELP SESSION; (Session level time zone setting is -08:00) SELECT loc_id, timestmp_with_zone FROM zone_test; loc_Id timestmp_with_zone ------------ ------------------------------------- GMT 1999-04-15 10:30:00+00:00 (10:30 GMT) PST 1999-04-15 10:30:00-08:00 (10:30 PST) SELECT loc_id, CAST(timestmp_with_zone AS TIMESTAMP(0)) FROM zone_test; loc_id timestmp_with_zone (Note: All times are represented in PST) ----------- ----------------------------- GMT 1999-04-15 02:30:00 (at 10:30 GMT, it's 02:30 PST) PST 1999-04-15 10:30:00 (at 10:30 PST, it's 10:30 PST) INSERT INTO zone_test (’PST',timestamp '1999-04-15 10:30:00'); (Note: zone is defaulted) Note: A Time or Timestamp is “normalized” when the zone is implicit. 376

377 Working With Zones (3 of 4) INSERT INTO zone_test /* Hong Kong local time */ (’HKT',TIMESTAMP '1999-04-15 10:30:00+08:00'); (Zone is explicit) SELECT loc_id, timestmp_with_zone FROM zone_test; SELECT loc_id, CAST(timestmp_with_zone AS TIMESTAMP(0)) FROM zone_test; loc_id timestmp_with_zone (Note: Time Zones are shown as explicit) ----------- -------------------------------------- GMT 1999-04-15 10:30:00+00:00 (10:30 GMT) PST 1999-04-15 10:30:00-08:00 (10:30 PST) HKT 1999-04-15 10:30:00+08:00 (10:30 in Hong Kong) loc_id timestmp_with_zone (All times are normalized to PST, the default) ---------- ---------------------------- GMT 1999-04-15 02:30:00 (When it's 10:30 GMT, it's 02:30 PST) PST 1999-04-15 10:30:00 (When it's 10:30 PST, it's 10:30 PST) HKT 1999-04-14 18:30:00 (When it's 10:30 in HK, it's 18:30 of previous day PST) For zone-independent processing, use default ‘00:00’ For zone-dependent processing, set default appropriately Timestamp and Time normalize default time zone into display Timestamp and Time WITH TIME ZONE show explicit zone Reminders 377

378 SET TIME ZONE LOCAL; (Resets time zone back to 00:00) SELECT loc_id, CAST(timestmp_with_zone AS TIMESTAMP(0)) FROM zone_test; loc_id timestmp_with_zone (All times are displayed in normalized GMT) ----------- ---------------------------- GMT 1999-04-15 10:30:00 ( When it's 10:30 GMT, it's 10:30 in GMT) PST 1999-04-15 18:30:00 (When it's 10:30 PST, it's 18:30 in GMT) HKT 1999-04-15 02:30:00 (When it's 10:30 in HK, it's 02:30 in GMT) 378

379 Working With Zones (4 of 4) The AT LOCAL option shows the time relative to the local time zone setting with explicit time zone. SELECT loc_id, timestmp_with_zone AT LOCAL FROM zone_test; SELECT loc_Id, CAST(timestmp_with_zone AS TIMESTAMP(0)) FROM zone_test ORDER BY 2; loc_id timestmp_with_zone AT LOCAL -------- ------------------------------------------ GMT 1999-04-15 02:30:00-08:00 HKT 1999-04-14 18:30:00-08:00 PST 1999-04-15 10:30:00-08:00 loc_id timestmp_with_zone -------- ---------------------------- HKT 1999-04-14 18:30:00 GMT 1999-04-15 02:30:00 PST 1999-04-15 10:30:00 (Note: Order is based on normalized PST time.) SELECT loc_id, timestmp_with_zone FROM zone_test ORDER BY 2; loc_id timestmp_with_zone -------- ------------------------------------- GMT 1999-04-15 10:30:00+00:00 HKT 1999-04-15 10:30:00+08:00 PST 1999-04-15 10:30:00-08:00 (Note: Order is zone independent.) 379

380 SET TIME ZONE LOCAL; (RESETS TIME ZONE BACK TO 00:00) SELECT loc_id, timestmp_with_zone AT LOCAL FROM zone_test; loc_id timestmp_with_zone AT LOCAL ------ -------------------------------------------- GMT 1999-04-15 10:30:00+00:00 HKT 1999-04-15 02:30:00+00:00 PST 1999-04-15 18:30:00+00:00 SET TIME ZONE INTERVAL -'08:00' HOUR TO MINUTE;(Set to PST) 380

381 Extracting From Timestamp With Zone SELECT EXTRACT(timezone_hour FROM timestmp_with_zone) FROM zone_test; EXTRACT(ZONE HOUR FROM timestmp_with_zone) ------------------------------------------------------------------------ -8 0 8 SELECT EXTRACT(DAY FROM timestmp_with_zone) FROM zone_test; EXTRACT(DAY FROM timestmp_with_zone) ------------------------------------------------------------ 15 SET TIME ZONE INTERVAL -'08:00' HOUR TO MINUTE; SELECT CAST(timestmp_with_zone AS TIMESTAMP) AS xyz,EXTRACT(DAY FROM xyz) FROM zone_test; xyz EXTRACT(DAY FROM timestmp_with_zone) --------------------------------------- ------------------------------------------------------------ 1999-04-15 10:30:00.000000 15 1999-04-14 18:30:00.000000 14 1999-04-15 02:30:00.000000 15 381

382 Extracting From Timestamp (Without Zone) Add 5 days, 2 hrs and 10 mins to the specified timestamp: SELECT TIMESTAMP '1999-12-15 09:45:20‘ + INTERVAL '05 02:10' DAY TO MINUTE; 1999-12-20 11:55:20 Extract the day from the resulting timestamp: SELECT EXTRACT (DAY FROM (TIMESTAMP '1999-12-15 09:45:20‘ + INTERVAL '05 02:10' DAY TO MINUTE)); 20 Extract the minute from the resulting timestamp: SELECT EXTRACT (MINUTE FROM (TIMESTAMP '1999-12-15 09:45:20‘ + INTERVAL '05 02:10' DAY TO MINUTE)); 55 382

383 Overlap Function The OVERLAP function tests whether there is an overlap between two time periods. SELECT 'They overlap' WHERE (DATE '1999-01-01', DATE '1999-11-30') OVERLAPS (DATE '1999-10-15', DATE '1999-12-31'); They overlap. SELECT 'They overlap' WHERE (DATE '1999-01-01', DATE '1999-10-15') OVERLAPS (DATE '1999-10-15', DATE '1999-12-31'); *** Query completed. No rows found. (Note: Sharing a single common point does not qualify as an overlap) SELECT 'They overlap' WHERE (TIME '10:00:00', TIME '01:00:00') OVERLAPS (TIME '01:01:00', TIME '03:00:00'); They overlap. (Note: Each interval is automatically sequenced putting earliest first.) (The following is an equivalent query) SELECT 'They overlap' WHERE (TIME '01:00:00', TIME '10:00:00') OVERLAPS (TIME '01:01:00', TIME '03:00:00'); They overlap. SELECT 'They overlap' WHERE (TIME '01:00:00', NULL ) OVERLAPS (TIME '01:01:00', TIME '03:00:00'); *** Query completed. No rows found. (Note: When one side of interval is null, test if the other side is within range) 383

384 Overlap Data Type Options Date1, Date2 Time1, Time2 Timestamp1, Timestamp2 Date1, Interval Time1, Interval Timestamp1, Interval OVERLAPS (Compatible interval) SELECT 'They overlap' WHERE (TIMESTAMP '1999-10-15 01:00:00',TIMESTAMP'1999-10-15 02:00:00') OVERLAPS (TIMESTAMP '1999-10-15 01:01:00', TIMESTAMP '1999-10-15 03:00:00'); They overlap. (Note: Timestamp overlap requires only time overlap.) SELECT 'They overlap' WHERE (CURRENT_TIME, INTERVAL '1' HOUR) OVERLAPS (CURRENT_TIME, INTERVAL -'1' HOUR); *** Query completed. No rows found. (Note: Common point does not overlap.) 384

385 SELECT 'They overlap' WHERE (CURRENT_TIME, CURRENT_TIME + INTERVAL '1' HOUR) OVERLAPS (CURRENT_TIME, CURRENT_TIME - INTERVAL '1' HOUR); *** Query completed. No rows found. (Note: Same as previous query.) SELECT 'They overlap' WHERE (CURRENT_TIME, INTERVAL '1' HOUR) OVERLAPS (CURRENT_TIME + INTERVAL '1' SECOND, INTERVAL -'1' HOUR); They overlap (Note: They overlap by one second.) 385

386 Module 27 Teradata V2R3 Special Features 386

387 After completing this module, a student should see how to: Insert into a table using default values feature. Perform string functions using the POSITION feature. Test case sensitivity with the LOWER attribute. Rename a column of a table 387

388 Inserting Default Values INSERT INTO tablename DEFAULT VALUES; Will insert defined default values into each column. If no default is defined, will insert a null. If no default defined and null not allowed, insert will fail. INSERT INTO test_tbl DEFAULT VALUES; SELECT * FROM test_tbl; CREATE TABLE test_tbl (cola SMALLINT NOT NULL DEFAULT 22,colb CHAR(1),colc DATE DEFAULT 1000101 FORMAT 'YYYY-MM-DD',cold DEC(3,2) NOT NULL WITH DEFAULT,cole TIME(0) DEFAULT CURRENT_TIME,colf INT DEFAULT TIME,colg CHAR(8) DEFAULT USER); cola colb colc cold cole colf colg ------- ----- --------------- ------ ----------- ----------- -------- 22 ? 2000-01-01.00 11:14:14 111414 PED INSERT INTO test_tbl DEFAULT VALUES; SELECT * FROM test_tbl; cola colb colc cold cole colf colg ------- ----- --------------- ------ ----------- ----------- -------- 22 ? 2000-01-01.00 11:14:14 111414 PED 22 ? 2000-01-01.00 11:14:37 111437 PED 388

389 Defaulting Methods INSERT INTO test_tbl VALUES (,,,,,, ); SELECT * FROM test_tbl; cola colb colc cold cole colf colg ------- ----- --------------- ------ ----------- ----------- -------- 22 ? 2000-01-01.00 11:14:14 111414 PED 22 ? 2000-01-01.00 11:14:37 111437 PED 22 ? 2000-01-01.00 11:15:03 111503 PED ALTER TABLE test_tbl ADD colh SMALLINT NOT NULL; *** Failure 3559 Column COLH is not NULL and it has no default value. ALTER TABLE test_tbl ADD colh SMALLINT NOT NULL WITH DEFAULT; INSERT INTO test_tbl DEFAULT VALUES; SELECT * FROM test_tbl; cola colb colc cold cole colf colg colh ------- ----- --------------- ------ ----------- ----------- -------- ------- 22 ? 2000-01-01.00 11:14:14 111414 PED 0 22 ? 2000-01-01.00 11:14:37 111437 PED 0 22 ? 2000-01-01.00 11:15:03 111503 PED 0 22 ? 2000-01-01.00 11:15:59 111559 PED 0 (Traditional defaulting) *** Failure 3811 Column 'a' is NOT NULL. Give the column a value. CREATE TABLE abc (a INT NOT NULL); INSERT INTO abc DEFAULT VALUES; 389

390 Creating Teradata Mode Tables CREATE TABLE case_nsp_test (col1 CHAR(7),col2 CHAR(7)); SHOW TABLE case_nsp_test; CREATE SET TABLE PED.case_nsp_test,NO FALLBACK, NO BEFORE JOURNAL, NO AFTER JOURNAL ( col1 CHAR(7) CHARACTER SET LATIN NOT CASESPECIFIC, col2 CHAR(7) CHARACTER SET LATIN NOT CASESPECIFIC) PRIMARY INDEX ( col1 ); (Columns created in Teradata mode are defaulted to Not Casespecific. ) INSERT INTO case_nsp_test VALUES('LAPTOP', 'laptop'); SELECT * FROM case_nsp_test WHERE col1 = col2; col1 col2 ------------ --------- LAPTOP laptop Because both columns are defined as NCS, all comparison tests will be done NCS. 390

391 Creating ANSI Mode Tables.SET SESSION TRANSACTION ANSI; CREATE TABLE case_sp_test (col1 CHAR(7),col2 CHAR(7)); SHOW TABLE case_sp_test; CREATE MULTISET TABLE PED.case_sp_test,NO FALLBACK, NO BEFORE JOURNAL, NO AFTER JOURNAL ( col1 CHAR(7) CHARACTER SET LATIN CASESPECIFIC, col2 CHAR(7) CHARACTER SET LATIN CASESPECIFIC) PRIMARY INDEX ( col1 ); INSERT INTO case_sp_test VALUES('LAPTOP', 'laptop'); SELECT * FROM case_sp_test WHERE col1 = col2; *** Query completed. No rows found. SELECT * FROM case_sp_test WHERE UPPER(col1) = UPPER(col2); col1 col2 ------------ --------- LAPTOP laptop Note: In ANSI, it is necessary to perform a case-blind test to do non-case specific testing. 391

392 The LOWER Function (1 of 2) Allows case-blind testing on case specific strings. Allows storage and retrieval of lower case characters. The LOWER function SELECT * FROM case_sp_test WHERE LOWER(col1) = LOWER(col2); col1 col2 ------------ --------- LAPTOP laptop SELECT * FROM case_sp_test; UPDATE case_sp_test SET col2 = col1; col1 col2 ------------ LAPTOP UPDATE case_sp_Test SET col1 = LOWER(col1); SELECT * FROM case_sp_test; col1 col2 ------------ laptop LAPTOP (Case blind test) The LOWER function provides the reverse capabilities of the UPPER function. 392

393 The LOWER Function (2 of 2) INSERT INTO case_sp_test VALUES ('LAPTOP', 'LAPTOP'); Insert a second row: SELECT * FROM case_sp_test; col1 col2 ---------- ------------ laptop LAPTOP LAPTOP SELECT * FROM case_sp_test WHERE col1 = col2; col1 col2 ----------- ------------ LAPTOP LAPTOP(Case sensitive result) SELECT * FROM case_sp_test WHERE col1 = LOWER(col2); col1 col2 -------- ------------ laptop LAPTOP SELECT * FROM case_sp_test WHERE col1(NOT CS) = col2(NOT CS); col1 col2 ----------- ------------ laptop LAPTOP LAPTOP LAPTOP (Case blind test but non-ANSI syntax) SELECT LOWER(col1) FROM case_test1; Lower(col1) ---------------- laptop laptop (Convert display to lowercase.) 393

394 POSITION Function SELECT INDEX('laptop','p'); Index('laptop','p') ---------------------- 3 The INDEX function is the traditional Teradata function for locating a string within a string. SELECT INDEX('laptop','top'); Index('laptop','top') ------------------------- 4 The POSITION function is the ANSI standard function for locating a string within a string. SELECT POSITION ('p' in 'laptop'); Position('p' in 'laptop') ----------------------------- 3 Position('top' in 'laptop') -------------------------------- 4 SELECT POSITION ('top' in 'laptop'); Both POSITION and INDEX are available functions Only POSITION is ANSI standard. 394

395 POSITION and Case Sensitivity SELECT POSITION (UPPER('top') IN 'laptop'); ANSI result Teradata result 0 4 SELECT POSITION (LOWER('TOP') IN 'laptop'); ANSI result Teradata result 4 SELECT POSITION (LOWER('TOP') IN 'LAPTOP'); ANSI result Teradata result 0 4 SELECT POSITION ('top' IN 'laptop'); ANSI result Teradata result 4 SELECT POSITION (’TOP' IN 'laptop'); ANSI result Teradata result 0 4 ANSI result implies an ANSI transaction mode session. Teradata result implies a BTET transaction mode session. 395

396 Renaming Columns The new name doesn’t already exist in the table. The column is not part of an index. The column is not part of any referential integrity constraints. A column may be renamed to a different name provided: CREATE TABLE rename_test (col1 INT,col2 INT,col3 INT) UNIQUE PRIMARY INDEX (col1),INDEX (col3); ALTER TABLE rename_test RENAME col2 TO colb; CREATE SET TABLE PED.rename_test,NO FALLBACK, NO BEFORE JOURNAL, NO AFTER JOURNAL ( col1 INTEGER, colb INTEGER, col3 INTEGER) UNIQUE PRIMARY INDEX ( col1 ) INDEX ( col3 ); 396

397 SHOW TABLE rename_test; ALTER TABLE rename_test RENAME col1 TO cola; Failure: Column COL1 is an index column and cannot be modified. ALTER TABLE rename_test RENAME col3 TO colc; Failure: Column COL3 is an index column and cannot be modified. 397

398 Summary of V2R3 User Features System Calendar OLAP features Triggers Global and Volatile Temporary tables ANSI Date/Time/Timestamp and Zone capabilities INSERT using Default Values LOWER function POSITION function Rename Columns The following topics were covered in this course: The following are additional features of V2R3: New Maximums: The SHOW command will show larger amounts of text. 64KB is the new max row size. Up to 64 tables may be joined. Up to 128 vprocs may be defined on a node. Up to 16K vprocs may be defined on a single system. New User-Based Features: Join Index Dynamic change of user priority 398

399 Temporary Password Expire feature Foundation for full internationalization New performance improvements to the DBMS software: Aggregation performance improvements Statistics enhancements Locking granularity improvements Recovery time improvements Update performance enhancements 399

400 Module 28 Using the RANDOM Function 400

401 After completing this module, a student should see how to: Use the RANDOM function to generate random numbers. Use the RANDOM function to generate random samples. Use the RANDOM function to generate test data. 401

402 RANDOM Function The RANDOM function may be used to generate a random number between a specified range. RANDOM (Lower limit, Upper limit) returns a random number between the lower and upper limits inclusive. Both limits must be specified. Example: Assign a random number between 1 and 9 to each department. SELECT department_number, RANDOM(1,9) FROM department; department_number Random(1,9) ----------------- ----------- 501 2 301 6 201 3 600 7 100 3 402 2 403 1 302 5 401 1 Note it is possible for random numbers to repeat. The RANDOM function is activated for each row processed, thus duplicate random values are possible. 402

403 Duplicate Random Values Duplicate value likelihood may be reduced by increasing the size of the RANDOM interval relative to the size of the table. Example: Assign a random number between 1 and 100 to each department. SELECT department_number, RANDOM(1,100) FROM department; department_number Random(1,100) ----------------- ------------- 501 15 301 19 201 71 600 75 100 61 402 41 403 81 302 31 401 59 Note that no duplicates were generated because the pool of possible values is over ten times the number of rows to be assigned. 403

404 Duplicate RANDOM Values (cont'd) Duplicate random values can be increased, by decreasing the size of the RANDOM interval relative to the size of the table. Example: Assign a random number between 1 and 3 to each department. SELECT department_number, RANDOM(1,3) FROM department; department_number Random(1,3) ----------------- ----------- 501 2 301 3 201 3 600 1 100 3 402 2 403 1 302 2 401 1 With only three values to distribute over nine rows, duplicates are necessary. 404

405 Consider the following distribution of employee salaries. Salary Range Count ------------- ------- $ 0 to < $30K 6 $30 to < $40K 9 $40 to < $50K 4 $50K + 7 Problem: Select a sample representing two thirds of the employees making under $30,000. Use the RANDOM function to accomplish this. Solution 1: SELECT employee_number, salary_amount FROM employee WHERE (salary_amount < 30000 AND RANDOM(1,3) < 3); employee_number salary_amount --------------- ------------- 1006 29450.00 1023 26500.00 1013 24500.00 Because of the nature of random number generation, we end up with a 50% sample (3 out of 6) instead of a 67% sample (4 out of 6). 405

406 RANDOM Sampling (cont'd) A sample can also be generated and with more accuracy using the SAMPLE function. Solution 2: SELECT employee_number, salary_amount FROM employee WHERE salary_amount < 30000 SAMPLE.67; employee_number salary_amount --------------- ------------- 1006 29450.00 1023 26500.00 1008 29250.00 1014 24500.00 406

407 Complex RANDOM Sampling The RANDOM function can be used multiple times in the same SELECT statement, It can be used to produce multiple samples, each using a separate criteria. Example: Create a sample consisting of approximately 67% from each of the under $50,000 salary ranges. SELECT employee_number, salary_amount FROM employee WHERE (salary_amount < 30000 AND RANDOM(1,3) < 3) OR (salary_amount BETWEEN 30001 AND 40000 AND RANDOM(1,3) < 3) OR (salary_amount BETWEEN 40001 AND 50000 AND RANDOM(1,3) < 3) ORDER BY 2; 407

408 employee_number salary_amount --------------- ------------- 1014 24500.00 1001 25525.00 1023 26500.00 1009 31000.00 1005 31200.00 1004 36300.00 1003 37850.00 1021 38750.00 1020 39500.00 1002 43100.00 1024 43700.00 1010 46000.00 1007 49700.00 The result shows the following distribution: Under $30,000 — 3 out of 6 (50%) Between $30,000 and $39,999 — 6 out of 9 (67%) Between $40,000 and $49,999 — 4 out of 4 (100%) 408

409 Complex RANDOM Sampling (cont'd) Changing the size of the RANDOM range can affect the size of the returned sample. Example: Perform the same query but change the size of the RANDOM range to 100. SELECT employee_number, salary_amount FROM employee WHERE (salary_amount < 30000 AND RANDOM(1,100) < 68) OR (salary_amount BETWEEN 30001 AND 40000 AND RANDOM(1,100) < 68) OR (salary_amount BETWEEN 40001 AND 50000 AND RANDOM(1,100) < 68) ORDER BY 2; 409

410 employee_number salary_amount --------------- ------------- 1013 24500.00 1023 26500.00 1005 31200.00 1022 32300.00 1004 36300.00 1003 37850.00 1007 49700.00 This result shows the following distribution: Under $30,000 — 2 out of 6 (33%) Between $30,000 and $39,999 — 4 out of 9 (44%) Between $40,000 and $49,999 — 1 out of 4 (25%) 410

411 Sample Sizing Issues The larger the pool of rows to be drawn from, the closer one can get to achieving a specific percentage of rows in the sample. SEL COUNT(*) FROM agent_sales WHERE (sales_amt BETWEEN 20000 and 39999); Returns 100 rows exactly (31 + 69) Each of the following examples attempts to return a 50% sample of the target rows. SEL COUNT(*) FROM agent_sales WHERE (sales_amt BETWEEN 20000 and 39999) AND RANDOM(1,100) < 51; Returns 58 rows or 58% 411

412 SEL COUNT(*) FROM agent_sales WHERE (sales_amt BETWEEN 20000 and 39999) AND RANDOM(1,10) < 6; Returns 53 rows or 53% SEL COUNT(*) FROM agent_sales WHERE (sales_amt BETWEEN 20000 and 39999) AND RANDOM(1,4) < 3; Returns 50 rows or 50% The smaller the RANDOM range is defined relative to the size of the pool of rows, the more accurately a specific percentage can be achieved. 412

413 Limitations On Use Of RANDOM RANDOM is non-ANSI standard RANDOM may be used in a SELECT list or a WHERE clause, but not both RANDOM may be used in Updating, Inserting or Deleting rows RANDOM may not be used with aggregate or OLAP functions RANDOM cannot be referenced by numeric position in a GROUP BY or ORDER BY clause 413

414 Module 29 Table Creation From Existing Tables 414

415 After completing this module, a student should see how to: Create empty tables based on existing table definitions. Create populated tables based on existing table definitions and data content. Create tables from multiple table sources. 415

416 Syntax: CREATE TABLE NewTableName AS ExistingTableName WITH NO DATA; Privileges Required: Create Table in target database/user space Select on source table Example: CREATE TABLE dept1 AS department WITH NO DATA; Creating Empty Tables Using Existing Definitions 416

417 Most standard column attributes are copied: Column names Data types Default values NOT NULL constraints CHECK constraints UNIQUE constraints PRIMARY KEY constraints Some attributes are not copied: References constraints Triggers (which reference source table) Statistics Most table level attributes are copied: Fallback options Journal options(permanent tables only) All indexes(except defined join indexes) Copied Attributes 417

418 Copied Attributes can be overridden Example: CREATE TABLE dept1, FALLBACK AS department WITH NO DATA UNIQUE INDEX (department_name) ; Overriding Copied Attributes 418

419 Creating Tables Using Subqueries Example: CREATE TABLE emp1 AS (SELECT employee_number,department_number,salary_amount FROM employee) WITH NO DATA; SHOW TABLE emp1; CREATE SET TABLE emp1,NO FALLBACK, NO BEFORE JOURNAL, NO AFTER JOURNAL ( employee_number INTEGER, department_number INTEGER, salary_amount DECIMAL(10,2) NOT NULL) PRIMARY INDEX ( employee_number ); Contd.. 419

420 Creating Tables Using Subqueries Contd.. Subquery can include: Join expressions (including outer joins) Aggregates OLAP functions Embedded subqueries 420

421 Renaming Columns Two techniques: Either CREATE TABLE emp1 AS (SELECT employee_number AS emp,department_number AS dept,salary_amount AS sal FROM employee) WITH NO DATA; or CREATE TABLE emp1 (emp, dept, sal) AS (SELECT employee_number,department_number,salary_amount FROM employee) WITH NO DATA; Contd.. 421

422 SHOW TABLE emp1; CREATE SET TABLE PED1.emp1, NO FALLBACK, NO BEFORE JOURNAL, NO AFTER JOURNAL ( emp INTEGER,,dept INTEGER,sal DECIMAL(10,2)) PRIMARY INDEX ( emp ); Renaming Columns Contd.. 422

423 Changing Column Attributes Example 1: CREATE TABLE dept1 AS (SELECT department_number AS dept,CAST(budget_amount AS INTEGER) AS budget FROM department) WITH NO DATA; Example 2: CREATE TABLE dept1 (dept DEFAULT 0 UNIQUE NOT NULL, budget CHECK (budget > 0) ) AS (SELECT CAST(department_number AS INTEGER),CAST(budget_amount AS INTEGER) FROM department) WITH NO DATA; Note: Data type changes must be indicated within the subquery SELECT statement, not the parameter list. 423

424 Creating Populated Tables Using Existing Tables Use the CREATE TABLE…AS and the WITH DATA option to create populated tables from existing tables CREATE TABLE dept1 AS department WITH DATA; SELECT department_number AS dept_num,department_name AS dept_name,budget_amount AS budget,manager_employee_number AS mgr FROM dept1 ORDER BY 1; Contd.. 424

425 Creating Populated Tables Using Existing Tables Contd.. 425

426 Using Joins In A Subquery Example: CREATE TABLE dept3 AS (SELECT d.department_number, d.department_name, e.last_name AS mgr_name FROM department d INNER JOIN employee e ON e.employee_number = d.manager_employee_number ) WITH DATA; SHOW TABLE dept3; CREATE SET TABLE PED.dept3,NO FALLBACK, NO BEFORE JOURNAL, NO AFTER JOURNAL ( department_number SMALLINT, department_name CHAR(30) CHARACTER SET LATIN NOT CASESPECIFIC NOT NULL, mgr_name CHAR(20) CHARACTER SET LATIN NOT CASESPECIFIC) PRIMARY INDEX ( department_number ); 426

427 Using Calculations and Expressions Calculations can be used to provide column data Example: CREATE TABLE emp2(emp,last,hire,birth,hire_age) AS (SELECT employee_number,last_name,hire_date,birthdate,(hire_date - birthdate)/365.25 FROM employee) WITH DATA; SELECT * FROM emp2 WHERE emp < 1015 ORDER BY 1; Contd.. 427

428 Using Calculations and Expressions Contd.. 428

429 Overriding Data Types Default data types for calculated columns can be overridden in the Select subquery CREATE TABLE emp3 (emp,last,hire,birth,hire_age) AS (SELECT employee_number,last_name,hire_date,birthdate,CAST((hire_date - birthdate)/365.25 AS INTEGER) FROM employee) WITH DATA; SELECT * FROM emp2 WHERE emp < 1015 ORDER BY 1; Contd.. 429

430 Overriding Data Types Contd.. 430

431 Setting Default Titles Either: use TITLE phrase to change the column-heading CREATE TABLE monthly_sal_401 (emp, sal TITLE 'Monthly Salary') AS (SELECT employee_number,salary_amount/12 FROM employee WHERE department_number = 401) WITH DATA; SELECT * FROM monthly_sal_401; emp Monthly Salary ---- -------------- 1003 3154.17 1004 3025.00 1010 3833.33 1001 2127.08 1002 3591.67 1013 2041.67 1022 2691.67 431

432 Renaming Columns Using The AS Clause Or: use AS phrase to rename the column Example 1 CREATE TABLE monthly_sal_401 AS (SELECT employee_number AS emp,salary_amount/12 AS monthly_salary FROM employee WHERE department_number = 401) WITH DATA; Example 2 (using non-standard characters) CREATE TABLE monthly_sal_401 AS (SELECT employee_number AS emp,salary_amount/12 AS "Monthly Salary" FROM employee WHERE department_number = 401) WITH DATA; Note - Double-quoting the column-name allows non-standard characters in the column-name 432

433 Adding UNIQUE And PRIMARY KEY Constraints CREATE TABLE dept1 (deptno UNIQUE NOT NULL,deptname PRIMARY KEY NOT NULL,budget,manager) AS department WITH NO DATA; When adding PRIMARY KEY or UNIQUE constraints, it is necessary to also specify the NOT NULL attribute 433

434 Volatile and Temporary Tables CREATE GLOBAL TEMPORARY TABLE dept1 AS (SELECT * FROM department) WITH NO DATA; Cannot utilise WITH DATA clause when creating volatile and temporary tables using CREATE… AS Default is ON COMMIT DELETE ROWS May need to be altered ALTER TABLE dept1 ON COMMIT PRESERVE ROWS; Table must be populated separately using INSERT … SELECT INSERT INTO dept1 SELECT * FROM department; 434

435 Using DEFAULT Values CREATE TABLE dept1 (deptno, budget NOT NULL DEFAULT 0) AS (SELECT department_number, budget_amount FROM department) WITH NO DATA; Default values may be specified as column attributes of tables created by CREATE … AS 435

436 Populating NOT NULL Columns Population of NOT NULL columns may require special attention INSERT INTO dept1 SELECT department_number, COALESCE(budget_amount,0) FROM department; *** Failure 3604 Cannot place a null value in a NOT NULL field. INSERT INTO dept1 SELECT department_number, budget_amount FROM department; Contd.. 436

437 Populating NOT NULL Columns Contd.. SELECT * FROM dept1; deptno budget ------ --------- 501 308000.00 301 465600.00 201 293800.00 600.00 100 400000.00 402 308000.00 403 932000.00 302 226000.00 401 982300.00 437

438 Populating DEFAULT Columns Population of NOT NULL/DEFAULT columns may require special attention CREATE TABLE dept1 (deptno, budget NOT NULL DEFAULT 0) AS (SELECT department_number,budget_amount (DEC(10,2))) FROM department) WITH DATA; *** Failure 3604 Cannot place a null value in a NOT NULL field. CREATE TABLE dept1 (deptno, budget NOT NULL DEFAULT 0) AS (SELECT department_number,COALESCE(budget_amount,0) (DEC(10,2)) FROM department) WITH DATA; Contd.. 438

439 SELECT * FROM dept1; deptno budget ------ --------- 501 308000.00 301 465600.00 201 293800.00 600.00 100 400000.00 402 308000.00 : Populating DEFAULT Columns Contd.. 439

440 Module 30 Using The COUNT Window Function 440

441 After completing this module, a student should see how to: Produce reports requiring groupbased counts using the COUNT Window function 441

442 COUNT Window Function COUNT Window function may be used to perform the following operations: Count the number of rows in a defined group Count the number of rows in all groups Similar Functionality to WITH and WITH…BY WITH WITH…BY COUNT Window Teradata ExtensionYESNO ANSI NO YES Use with BTEQ YES YES Use with ODBC NO YES 442

443 Using WITH...BY For Group Counts Show employee details and the number of employees in each department using the WITH…BY facility: SELECT last_name AS Name,salary_amount AS Salary,department_number AS Dept FROM employee WHERE Dept IN (401,403) WITH COUNT(Dept)(TITLE 'Dept_Count') BY Dept; Contd.. 443

444 Name Salary Dept ------- ---------- ----- Trader 37850.00 401 Hoover 25525.00 401 Johnson 36300.00 401 Phillips 24500.00 401 Machado 32300.00 401 Brown 43100.00 401 Rogers 46000.00 401 ----- Dept_Count 7 Lombardo 31000.00 403 Brown 43700.00 403 Villegas 49700.00 403 Hopkins 37900.00 403 Charles 39500.00 403 Ryan 31200.00 403 ----- Dept_Count 6 Using WITH...BY For Group Counts Contd.. Note that the output from this query is a non-relational output. The sub-total rows are of a different format than the data rows. 444

445 Using The COUNT Window Function For Group Counts SELECT last_name AS Name,salary_amount AS Salary,department_number AS Dept,COUNT(Salary) OVER (PARTITION BY Dept ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS Dept_Count FROM employee WHERE Dept IN (401,403); Name Salary Dept Dept_Count ---------- -------- ---- ---------- Trader 37850.00 4017 Johnson 36300.00 4017 Phillips 24500.00 401 7 Rogers 46000.00 401 7 Machado 32300.00 401 7 Brown 43100.00 401 7 Hoover 25525.00 401 7 Charles 39500.00 403 6 Brown 43700.00 403 6 Hopkins 37900.00 403 6 Ryan 31200.00 403 6 Lombardo 31000.00 403 6 Villegas49700.00 403 6 Note that the generated output is relational in form. All rows and columns are uniform. 445

446 Using WITH For Final Counts Show employee details and total number of employees: SELECT last_name AS Name,salary_amount AS Salary,department_number AS Dept FROM employee WHERE Dept IN (401,403) WITH COUNT(Dept)(TITLE 'Total_Count') ORDER BY 3,1; Name Salary Dept ---------- -------- ---- Brown 43100.00 401 Hoover 25525.00 401 Johnson 36300.00 401 Machado 32300.00 401 Phillips 24500.00 401 Rogers 46000.00 401 Trader 37850.00 401 Brown 43700.00 403 Charles 39500.00 403 Hopkins 37900.00 403 Lombardo 31000.00 403 Ryan 31200.00 403 Villegas 49700.00 403 ---- Total_Count 13 Note that the output from this query is a non-relational output. The total row is of a different format than the data rows. 446

447 Using COUNT Window Function For Final Counts Show employee details and total number of employees: SELECT last_name AS Name,salary_amount AS Salary,department_number AS Dept,COUNT(salary) OVER (ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS Dept_Count FROM employee WHERE Dept IN (401,403) ORDER BY 3,1; Note that the generated output is relational in form. All rows and columns are uniform. Name Salary Dept Total_Count -------- -------- ---- ---------- Brown 43100.00 401 13 Hoover 25525.00 401 13 Johnson 36300.00 401 13 Machado 32300.00 401 13 Phillips 24500.00 401 13 Rogers 46000.00 401 13 Trader 37850.00 401 13 Brown 43700.00 403 13 Charles 39500.00 403 13 Hopkins 37900.00 403 13 Lombardo 31000.00 403 13 Ryan 31200.00 403 13 Villegas 49700.00 403 13 447

448 Combining COUNT Window With RANK Review of RANK Function: Rank the agents between 200 and 214 by sales amount. SELECT agent_id, sales_amt AS sales, RANK(sales) AS "Rank" FROM agent_sales WHERE agent_id BETWEEN 200 AND 214; agent_id sales Rank --------- ------ ----- 200 30550 1 204 30220 2 206 20300 3 203 20280 4 208 20270 5 209 20210 6 214 20110 7 213 10240 8 201 10210 9 212 10160 10 Note that the default order of the report is in descending sales amount. 448

449 RANK Ascending Sequence We may reverse the ranking assignments using an 'ascending' ranking. Rank the agents in ascending rank by sales amount. SELECT agent_id, sales_amt AS sales, RANK(sales ASC) AS "Rank" FROM agent_sales WHERE agent_id BETWEEN 200 AND 214; agent_id sales Rank --------- ------ ----- 212 10160 1 20110210 2 213 10240 3 214 20110 4 209 20210 5 208 20270 6 203 20280 7 206 20300 8 204 30220 9 200 30550 10Contd.. Note that the Rank #1 is now assigned to thelowest sales producer. 449

450 RANK Ascending Sequence (..cont'd) We may reverse the ranking assignments using an 'ascending' ranking. Rank the agents in ascending rank by sales amount. Now add an ORDER BY clause to change the sequence of the report. SELECT agent_id, sales_amt AS sales, RANK(sales ASC) AS "Rank" FROM agent_sales WHERE agent_id BETWEEN 200 AND 214 ORDER BY 2 DESC; agent_id sales Rank --------- ------ ----- 200 30550 10 204 302209 206 20300 8 203 20280 7 208 20270 6 209 20210 5 214 20110 4 213 10240 3 201 10210 2 212 10160 1 Note that the ranking assignments do not change, only the sequence of the report. The lowest producer is still ranked #1 450

451 Using COUNT Window And RANK For Percentiles Including a COUNT Window column and divide the Rank by it produces percentiles SELECT agent_id AS Agent_id, sales_amt AS Sales, RANK(sales ASC)AS "Rank", COUNT(sales) OVER (ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS "Total", "Rank" * 1.00 / "Total" AS Rank_ratio FROM agent_sales WHERE agent_id BETWEEN 200 AND 214 ORDER BY 2 DESC; Agent_id Sales Rank Total Rank_ratio -------- ----- ---- ----- ---------- 20030550 10 10 1.00 20430220 9 10.90 206 20300 8 10.80 203 20280 7 10.70 208 20270 6 10.60 209 20210 5 10.50 214 20110 4 10.40 213 10240 3 10.30 201 10210 2 10.20 212 10160 1 10.10 Note that the Rank_ratio amounts may be regarded as percentiles i.e., agent 200 is in the top percentile,agent 204 is in the 90th percentile etc 451

452 Using RANK And COUNT Window To Produce Ratings Example: Rate the top 20% as 'A', the middle 60% as 'B', and the bottom 20% as 'C‘ SELECT agent_id, sales_amt AS sales, RANK(sales ASC) AS "Rank", COUNT(sales) OVER (ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS "Total", "Rank" * 1.00 / "Total" AS rank_ratio, (CASE WHEN rank_ratio <.21 THEN 'C' WHEN rank_ratio BETWEEN.21 AND.80 THEN 'B' ELSE 'A' END) AS rating FROM agent_sales WHERE agent_id BETWEEN 200 AND 220 ORDER BY 2 DESC;Contd.. 452

453 Agent_id Sales Rank Total Rank_ratio rating --------- ------- ---- ----- ------- ------ 200 30550 16 16 1.00 A 215 30440 15 16.94 A 204 30220 14 16.88 A 206 20300 13 16.81 A 203 20280 12 16.75B 208 20270 11 16.69B 216 20240 10 16.62B 209 20210 9 16.56B 218 20190 8 16.50 B 214 20110 7 16.44 B 217 18050 6 16.38 B 213 10240 5 16.31 B 201 10210 4 16.25 B 212 10160 3 16.19 C 220 10120 2 16.12 C 219 10100 1 16.06 C Using RANK And COUNT Window To Produce Ratings Contd.. 453

454 Using COUNT Window Instead Of Derived Table Aggregation Produce a report showing how many agents fall into each sales revenue range using $10,000 increments: SELECT DISTINCT CASE WHEN sales_amt < 10000 THEN '$0K - <$10K ' WHEN sales_amt < 20000 THEN '$10K - <$20K' WHEN sales_amt < 30000 THEN '$20K - <$30K' WHEN sales_amt < 40000 THEN '$30K - <$40K' WHEN sales_amt < 50000 THEN '$40K - <$50K' ELSE 'Over $50K' END AS Sales_Range,COUNT(sales_range) OVER (PARTITION BY Sales_Range ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS Group_Count FROM agent_sales ORDER BY 1; An alternative approach to using a derived table Sales_Range Group_Count ------------ ----------- $0K - <$10K 4 $10K - <$20K 121 $20K - <$30K 69 $30K - <$40K 31 $40K - <$50K 8 Over $50K 1 454

455 By percentile, show how many agents fall within each group: SELECT DISTINCT CASE WHEN sales_amt < 10000 THEN 'Below $10K' WHEN sales_amt < 20000 THEN 'Below $20K' WHEN sales_amt < 30000 THEN 'Below $30K' WHEN sales_amt < 40000 THEN 'Below $40K' WHEN sales_amt < 50000 THEN 'Below $50K' ELSE 'Over $50K' END AS Sales_Range,COUNT(sales_range) OVER (PARTITION BY Sales_Range ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS Group_Count,Group_Count * 1.00 / cnt*100 (FORMAT 'ZZ9%') AS "Percentile" FROM agent_sales CROSS JOIN (SELECT COUNT(*) FROM agent_sales) temp (cnt) ORDER BY 1; Contd.. Using COUNT Window With Derived Tables 455

456 Sales_Range Group_Count Percentile ----------- ----------- --------- Below $10K 4 2% Below $20K 121 52% Below $30K 69 29% Below $40K 31 13% Below $50K 8 3% Over $50K 1 0% 456

457 COUNT Window And QUANTILE COUNT Window is closely related to Quantile: SELECT agent_id, sales_amt, QUANTILE(100,sales_amt) AS Quant, (RANK(sales_amt ASC) - 1)*100 / COUNT(sales_amt) OVER (ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS Rank_Gcount FROM agent_sales WHERE agent_id BETWEEN 200 AND 220 ORDER BY 3; Contd.. 457

458 Agent_id sales_amt Quant Rank_Gcount --------- ------- ----- --------- 219 10100 0 0 220 10120 6 6 212 10160 12 12 201 10210 18 18 213 10240 25 25 217 18050 31 31 214 20110 37 37 218 20190 43 43 209 20210 50 50 216 20240 56 56 208 20270 62 62 203 20280 68 68 206 20300 75 75 20430220 81 81 215 30440 87 87 20030550 93 93 458

459 Summary The COUNT Window function: produces a group count in conjunction with each detail row is an ANSI standard function may not be combined in a SELECT with standard aggregate functions (i.e. SUM, COUNT, AVG, MIN, MAX) may not be combined in a SELECT with WITH and/or WITH...BY clauses 459

460 Module 31 Using The SUM Window Function 460

461 After completing this module, a student should see how to: Produce reports requiring groupbased sums using the SUM Window function 461

462 SUM Window Function SUM Window function may be used to perform the following operations: Sum a column from rows in a defined group Sum a column from all rows in all groups Similar Functionality to WITH and WITH…BY WITH WITH…BY SUM Window Teradata Extension YES NO ANSI NO YES Use with BTEQ YES YES Use with ODBC NO YES 462

463 Using WITH...BY For Group Totals Show sales details and sub-totals by store using the WITH…BY facility: SELECT storeid, prodid, sales FROM salestbl WITH SUM(sales) BY storeid ORDER BY 1,2; Note that the output from this query is a non-relational output. The sub-total rows are of a different format than the data rows. storeid prodid sales ------- ------- --------- 1001 A 100000.00 1001 C 60000.00 1001 D 35000.00 1001 F 150000.00 --------- Sum(sales) 345000.00 1002 A 40000.00 1002 C 35000.00 1002 D 25000.00 --------- Sum(sales) 100000.00 1003 A 30000.00 1003 B 65000.00 1003 C 20000.00 1003 D 50000.00 --------- Sum(sales) 165000.00 463

464 Using The SUM Window Function For Group Totals SELECT storeid, prodid, sales, SUM(sales) OVER (PARTITION BY storeid ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) FROM salestbl ORDER BY 1,2; storeid prodid sales Group Sum(sales) ------- ------- --------- ---------------- 1001 A 100000.00 34500.00 1001 C 60000.00 34500.00 1001 D 35000.00 34500.00 1001 F 150000.00 34500.00 1002 A 40000.00 10000.00 1002 C 35000.00 10000.00 1002 D25000.00 10000.00 1003 A 30000.00 16500.00 1003 B 65000.00 16500.00 1003 C 20000.00 16500.00 1003 D50000.00 16500.00 Note that the generated output is relational in form. All rows and columns are uniform. 464

465 Using WITH For Final Totals Show store details and total sales across all stores: SELECT storeid, prodid, sales FROM salestbl WITH SUM(sales) ORDER BY 1,2; Storeid prodid sales ------- ------- --------- 1001 A 100000.00 1001 C 60000.00 1001 D 35000.00 1001 F 150000.00 1002 A 40000.00 1002 C 35000.00 1002 D 25000.00 1003A 30000.00 1003 B 65000.00 1003 C 20000.00 1003 D 50000.00 --------- Sum(sales) 610000.00 Note that the output from this query is a non-relational output. The total row is of a different format than thedata rows. 465

466 Using SUM Window Function For Final Totals Show store details and total sales across all stores: SELECT storeid, prodid, sales, SUM(sales) OVER (ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) FROM salestbl ORDER BY 1,2; storeid prodid sales Group Sum(sales) ------- ------- --------- ---------------- 1001 A 100000.00 61000.00 1001 C 60000.00 61000.00 1001 D 35000.00 61000.00 1001 F 150000.00 61000.00 1002 A 40000.00 61000.00 1002 C 35000.00 61000.00 1002 D 25000.00 61000.00 1003 A 30000.00 61000.00 1003 B 65000.00 61000.00 1003 C 20000.00 61000.00 1003 D 50000.00 61000.00 Note that the generated output is relational in form. All rows and columns are uniform. 466

467 Combining SUM Window With RANK Show the rank of sales for the top two products in each store and the total they represent for each store. SELECT storeid, prodid, sales, RANK(sales) AS "Rank", SUM(sales) OVER (PARTITION BY storeid ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS GroupTotal FROM salestbl GROUP BY storeid QUALIFY RANK(sales) <=2 ; storeid prodid sales Rank GroupTotal ------- ------- --------- ----------- ---------------- 1001 F 150000.00 1 345000.00 1001 A 100000.00 2 345000.00 1002 A 40000.00 1 100000.00 1002 C 35000.00 2 100000.00 1003 B 65000.00 1 165000.00 1003 D 50000.00 2 165000.00 467

468 SUM Window Used In Calculations EXAMPLE: Show the rank of sales for the top twoproducts in each store, the total they represent for each store, and the percent contribution to the total store sales. SELECT storeid,prodid,sales,RANK(sales) AS "Rank",SUM(sales) OVER (PARTITION BY storeid ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS Sumsales,sales*100 / Sumsales (DEC(3,1)) AS "Percent//Contrib" FROM salestbl GROUP BY storeid QUALIFY RANK(sales) <=2 ORDER BY 1,6 DESC; Percent storeid prodid sales Rank Sumsales Contrib ----------- ------ ----------- ----------- ----------- ------- 1001 F150000.00 1 345000.00 43.5 1001 A100000.00 2 345000.00 29.0 1002 A40000.00 1100000.00 40.0 1002 C 35000.00 2100000.00 35.0 1003 B 65000.00 1 165000.00 39.4 1003 D 50000.00 2 165000.00 30.3 468

469 Summary The SUM Window function: produces a group sum in conjunction with each detail row is an ANSI standard function may not be combined in a SELECT with standard aggregate functions (i.e. SUM, COUNT, AVG, MIN, MAX) may not be combined in a SELECT with WITH and/or WITH...BY clauses 469

470 Module 32 ANSI Equivalent OLAP Functions 470

471 After completing this module, a student should see how to: Use ANSI standard syntax to create OLAP queries. Translate Teradata OLAP functions to ANSI OLAP functions. Use the Teradata OLAP extensions for determining Quantiles, Random numbers, Moving Linear Regression and Moving Differences. 471

472 RANK Function Example: Rank the top three products across all stores by revenue. Teradata SELECT storeid, prodid, sales, RANK(sales) AS Rank_Sales FROM salestbl QUALIFY Rank_Sales <= 3 ; ANSI SELECT storeid, prodid, sales, RANK( ) OVER (ORDER BY sales DESC) AS Rank_Sales FROM salestbl QUALIFY rank_sales <= 3; storeid prodid sales Rank_Sales ----------- ------ ----------- ----------- 1001 F 150000.001 1001 A 100000.00 2 1003 B 65000.00 3 In Teradata syntax, descending sequence is the default. In ANSI syntax, ascending sequence is the default. 472

473 RANK Function With Groupings Example: Show a ranking of the top three products acrossall stores and the revenue generated by them. Teradata SELECT storeid, prodid, sales, RANK(sales) AS Rank_Sales FROM salestbl GROUP BY storeid QUALIFY Rank_Sales <= 3 ; ANSI SELECT storeid, prodid, sales, RANK( ) OVER (PARTITION BY storeid ORDER BY sales DESC) AS rank_sales FROM salestbl QUALIFY rank_sales <= 3; storeid prodid sales Rank_Sales ----------- ------ ----------- ----------- 1001 F 150000.00 1 1001 A 100000.00 2 1001 C 60000.00 3 1002 A 40000.00 1 1002 C 35000.00 2 1002 D 25000.00 3 1003 B 65000.00 1 1003 D 50000.00 2 1003 A 30000.00 3 473

474 CSUM Function Example: Produce a listing showing a cumulative sum of sales revenue by day over the first two months of 1998. Teradata SELECT salesdate, sales, CSUM(sales, salesdate) As "Csum" FROM daily_sales WHERE salesdate BETWEEN 980101 AND 980301; ANSI SELECT salesdate, sales, SUM(sales) OVER (ORDER BY salesdate ROWS UNBOUNDED PRECEDING) AS "Csum" FROM daily_sales WHERE salesdate BETWEEN 980101 AND 980301; salesdate sales Csum --------- ----------- ---------------- 98/01/01 150.00 150.00 98/01/02 200.00 350.00 98/01/03 250.00 600.00 98/01/05 350.00 950.00 98/01/10 550.00 1500.00 98/01/21 150.00 1650.00 98/01/25 200.00 1850.00 98/01/31 100.00 1950.00 98/02/01 150.00 2100.00 98/02/03 250.00 2350.00 98/02/06 350.00 2700.00 98/02/20 450.00 3700.00 98/02/27 350.00 4050.00 98/02/17 550.00 3250.00 474

475 MSUM Function Example: Produce a listing showing a moving sum of sales revenue for the first two months of 1998. Teradata SELECT salesdate, itemid, sales, MSUM(sales, 3, salesdate) AS "Msum" FROM daily_sales WHERE salesdate BETWEEN 980101 AND 980301; ANSI SELECT salesdate, itemid, sales, SUM(sales) OVER (ORDER BY salesdate ROWS 2 PRECEDING) AS "Msum" FROM daily_sales WHERE salesdate BETWEEN 980101 AND 980301; salesdate itemid sales Msum --------- ----------- ----------- ----------- 98/01/01 10 150.00 150.00 98/01/02 10 200.00 350.00 98/01/03 10 250.00 600.00 98/01/05 10 350.00 800.00 98/01/10 10 550.00 1150.00 98/01/21 10 150.00 1050.00 98/01/25 10 200.00 900.00 98/01/31 10 100.00 450.00 98/02/01 10 150.00 450.00 98/02/03 10 250.00 500.00 98/02/06 10 350.00 750.00 98/02/17 10 550.00 1150.00 98/02/20 10 450.00 1350.00 98/02/27 10 350.00 1350.00 475

476 MAVG Function Example: Produce a listing showing a weekly moving average of sales revenue for the first two months of 1998. Teradata SELECT salesdate, itemid, sales, MAVG(sales, 7, salesdate) AS "MAvg" WHERE salesdate BETWEEN 980101 AND 980301 FROM daily_sales; ANSI SELECT salesdate, itemid, sales, AVG(sales) OVER (ORDER BY salesdate ROWS 6 PRECEDING) AS "MAvg" WHERE salesdate BETWEEN 980101 AND 980301 FROM daily_sales; salesdate itemid sales MAvg ------ ----------- ----------- ----------- 98/01/01 10 150.00 150.00 98/01/02 10 200.00 175.00 98/01/03 10 250.00 200.00 98/01/05 10 350.00 237.50 98/01/10 10 550.00 300.00 98/01/21 10 150.00 275.00 98/01/25 10 200.00 264.29 98/01/31 10 100.00 257.14 98/02/01 10 150.00 250.00 98/02/03 10 250.00 250.00 98/02/06 10 350.00 250.00 98/02/17 10 550.00 250.00 98/02/20 10 450.00 292.86 98/02/27 10 350.00 314.29 476

477 Module 33 Aggregate Join Indexes 477

478 After completing this module, a student should see how to: Create an aggregate join index. Determine when an aggregate join index is advantageous. Determine when an aggregate join index is being used by the optimizer. 478

479 Join Index Review A Join Index is an optional index. Useful for: 1. Pre-join multiple tables 2. Distribute the rows of a single table on the hash value of a foreign key value 3. Aggregate one or more columns of a single table or multiple tables into a summary table 479

480 Why An Aggregate Index Summary Tables Queries involving aggregations over large tables are subject to high compute and I/o overhead. Summary tables often used to expedite their performance. Summary Tables Limitations Require the creation of a separate summary table Require initial population of the summary table Requires refresh of summary table Queries must access summary table, not the base table Multiple 'versions of the truth‘ Contd.. 480

481 Aggregate Indexes Aggregate indexes enhance the performance of the query while reducing the requirements placed on the user. An aggregate index is created similarly to a join index with the difference that sums, counts and date extracts may be used in the definition. The index is available only to the optimizer as a tool in its query planning. Aggregate indexes do not require any user maintenance. When underlying base table data is updated, the aggregate index totals are adjusted to reflect the changes. While this requires additional processing overhead when a base table is changed, it guarantees that the user will have up-to-date information in the index. 481

482 Aggregate Index Properties Aggregate Indexes are similar to other Join Indexes: Automatically kept up to date without user involvement. Never accessed directly by the user. Optional and provide an additional choice for the optimizer. Multiload and Fastload may NOT be used to load tables for which indexes are defined. Aggregate Indexes differ from other Join Indexes: Use the SUM and COUNT functions. Permit use of EXTRACT YEAR and EXTRACT MONTH from dates. Privileges required to create any join index: CREATE TABLE in the database or user which will own the join index, or INDEX privilege on each of the base tables. Additionally, you must have this privilege: DROP TABLE rights on each of the base tables. 482

483 Without An Aggregate Index Example: Show all monthly sales for item 10. SELECT EXTRACT(YEAR FROM salesdate)AS Yr, EXTRACT(MONTH FROM salesdate)AS Mon, SUM(sales) FROM daily_sales WHERE itemid = 10 AND Yr IN ('1997', '1998') GROUP BY 1,2 ORDER BY 1,2; Yr MonSum(sales) ----------- ----------- ----------- 1997 1 2150.00 19972 1950.00 1997 8 1950.00 19979 2100.00 1998 1 1950.00 1998 2 2100.00 1998 8 2200.00 1998 9 2550.00 483

484 EXPLAINing Without An Aggregate Index EXPLAIN SELECT EXTRACT(YEAR FROM salesdate)AS Yr, EXTRACT(MONTH FROM salesdate)AS Mon, SUM(sales) FROM daily_sales WHERE itemid = 10 AND Yr IN ('1997', '1998') GROUP BY 1,2 ORDER BY 1,2; Explanation -------------------------------------------------------------------------- 1. First, we do a SUM step to aggregate from PED1.daily_sales by way of the primary index "PED1.daily_sales.itemid = 10" with a residual condition of ("((EXTRACT(YEAR FROM (PED1.daily_sales.salesdate )))= 1997) OR ((EXTRACT(YEAR FROM (PED1.daily_sales.salesdate )))= 1998)"), and the grouping identifier in field 1. Aggregate Intermediate Results are computed locally, then placed in Spool 2. The size of Spool 2 is estimated with high confidence to be 1 to 1 rows. 2. Next, we do a single-AMP RETRIEVE step from Spool 2 (Last Use) by way of the primary index "PED1.daily_sales.itemid = 10" into Spool 1, which is built locally on that AMP. Then we do a SORT to order Spool 1 by the sort key in spool field1. The size of Spool 1 is estimated with high confidence to be 1 row. The estimated time for this step is 0.17 seconds. 3. Finally, we send out an END TRANSACTION step to all AMPs involved in processing the request. The contents of Spool 1 are sent back to the user as the result of statement 1. 484

485 Creating An Aggregate Index CREATE JOIN INDEX monthly_sales AS SELECT itemid AS Item,EXTRACT(YEAR FROM salesdate) AS Yr,EXTRACT(MONTH FROM salesdate) AS Mon,SUM(sales) AS SumSales FROM daily_sales GROUP BY 1,2,3; 485

486 EXPLAINing The Use Of Aggregate Index EXPLAIN SELECT EXTRACT(YEAR FROM salesdate)AS Yr, EXTRACT(MONTH FROM salesdate)AS Mon, SUM(sales) FROM daily_sales WHERE itemid = 10 AND Yr IN ('1997', '1998') GROUP BY 1,2 ORDER BY 1,2; Explanation ----------------------------------------------------------------------- 1.First, we do a SUM step to aggregate from join index table PED1.monthly_sales by way of the primary index "PED1.monthly_sales.Item = 10", and the grouping identifier in field 1. Aggregate Intermediate Results are computed locally, then placed in Spool 2. Thesize of Spool 2 is estimated with low confidence to be 4 to 4 rows. 2. Next, we do a single-AMP RETRIEVE step from Spool 2 (Last Use) by way of the primary index "PED1.monthly_sales.Item = 10" into Spool 1, which is built locally on that AMP. Then we do a SORT to order Spool 1 by the sort key in spool field1. The size of Spool 1is estimated with low confidence to be 4 rows. The estimated time for this step is 0.17seconds. 3. Finally, we send out an END TRANSACTION step to all AMPs involved in processing the request. The contents of Spool 1 are sent back to the user as the result of statement 1. 486

487 SHOWing The Aggregate Index SHOW JOIN INDEX monthly_sales; CREATE JOIN INDEX PED1.monthly_sales,NO FALLBACK AS SELECT COUNT(*)(FLOAT, NAMED CountStar ),PED1.daily_sales.itemid (NAMED Item ),EXTRACT(YEAR FROM (PED1.daily_sales.salesdate )) (NAMED Yr ),EXTRACT(MONTH FROM (PED1.daily_sales.salesdate )) (NAMED Mon ),SUM(PED1.daily_sales.sales )(NAMED SumSales ) FROM PED1.daily_sales GROUP BY PED1.daily_sales.itemid (NAMED Item ),EXTRACT(YEAR FROM (PED1.daily_sales.salesdate )) (NAMED Yr ),EXTRACT(MONTH FROM (PED1.daily_sales.salesdate )) (NAMED Mon ) PRIMARY INDEX ( Item ); All column names are fully qualified to the database level. A count of rows is automatically added if not specified in the definition. (COUNT(*) NAMED CountStar), thus supporting count aggregations. If both COUNT and SUM are carried in the index, AVERAGE calculations may also make use of the index. 487

488 Covering The Query - Example 1 An index is said to 'cover' the query (or cover part of the query) if the optimizer can generate the query results using the index as a replacement for one or more of the specified tables. SELECT itemid,SUM(sales) FROM daily_sales WHERE itemid = 10 GROUP BY 1; Example: Show the grand total sales for item 10 as contained in the daily_sales table. itemid Sum(sales) ------- --------- 10 16950.00 Explanation (Partial) ------------------------------------------------------------------------ 1. First, we do a SUM step to aggregate from join index table PED1.monthly_sales by way of the primary index "PED1.monthly_sales.Item = 10" with no residual conditions, and the grouping identifier in field 1. Aggregate Intermediate Results are computed locally, then placed in Spool 2. The size of Spool 2 is estimated with high confidence to be 1 to 1 rows. 488

489 Covering The Query - Example 2 Example: Show the total sales for item 10 for 1998. SELECT itemid,SUM(sales) FROM daily_sales WHERE itemid = 10 AND EXTRACT (YEAR FROM salesdate) = '1998' GROUP BY 1; itemid Sum(sales) ------- --------- 10 8800.00 Explanation (Partial) ------------------------------------------------------------------------ 1. First, we do a SUM step to aggregate from join index table PED1.monthly_sales by way of the primary index "PED1.monthly_sales.Item = 10", and the grouping identifier in field 1. Aggregate Intermediate Results are computed locally, then placedin Spool 2. The size of Spool 2 is estimated with high confidence to be 1 to 1 rows. 489

490 GSUM, GCOUNT, WITH, WITH...BY Functions Aggregate indexes are not used in conjunction with queries using SUM Window, COUNT Window, WITH or WITH...BY functions. Because these functions must process and display all qualifying detail rows, the value of the aggregate index is reduced. Explaining any query using these functions will validate that the index is not used. 490

491 Module 34 Stored Procedures - Part 1 491

492 Upon completion of this module, the student should see how to: Create, compile and execute a stored procedure. Implement cursor processing within a stored procedure. Create parameterized stored procedures. 492

493 Stored Procedure Basics A stored procedure is: - Teradata object (Type 'P') in a database/user space. - executable combination of two types of statements: SQL statements (Structured Query Language) SPL statements (Stored Procedure Language) SQL statements are used to access the rows of one or more tables in a Teradata database. SPL statements are used to add procedural control to the execution of the SQL statements. SPL contains most 3rd generation language features: Branch logic Conditional logic Error handling logic Exit logic Teradata stored procedures also include: optional input/output parameters optional 'condition handlers' for exception situations optional declared local variables SQL statements are usual, but not mandatory 493

494 Stored Procedure Properties Stored procedures have the following properties: Stored as object on the Teradata server. Compiled and executed on the Teradata server. Compiled object stored in a 'stored procedure table'. The source code, optionally, may also be stored. Require perm space. Using SQL, a user may perform the following operations on stored procedures: CREATE PROCEDURE REPLACE PROCEDURE RENAME PROCEDURE DROP PROCEDURE SHOW PROCEDURE Stored procedures are compatible with and supported by the following: BTEQ TeqTalk(DMTEQ) CLIv2 JDBC PP2 ANSI SQL99 (SQL3) ODBC PSM-96 QUERYMAN 494

495 Stored Procedure Advantages Stored procedures contain the SQL requests and the associated processing on the server side. Embedded SQL requests are forwarded to the Parser as individual requests and response sets are generated, processed and optionally returned to the procedure. The procedure may return answer set results, status codes or calculated results to the client application. Contd.. 495

496 Benefits of using stored procedures. Reduce network traffic between client and server. Move inter-request processing to the server side. Definition/enforcement of business rules on the server. Provide better transaction control. Provide better application security. 496

497 Parameterized Stored Procedures Three types of parameters : IN - Values that are supplied to the stored procedure at execution OUT - Values that are returned from the stored procedure to the user at call completion INOUT - Values that are both supplied to and returned from the stored procedure A stored procedure may contain up to 1024 parameters. Parameters are defined as any valid Teradata data type. Example: The following stored procedure tests an input parameter and outputs an evaluation of its value. CREATE PROCEDURE test_value(IN p1 INTEGER, OUT pmsg CHAR(30)) BEGIN IF p1 > 0 THEN SET pmsg = 'Positive value' ; ELSEIF p1 = 0 THEN SET pmsg = 'Zero Value' ; ELSE SET pmsg = 'Negative Value' ; END IF ; END ; 497

498 CALLing Stored Procedures To execute a stored procedure, the CALL statement is used. Example: Execute the procedure 'test_value'. CALL test_value (3, pmsg); pmsg ------------------------------ Positive value CALL test_value (0, pmsg); pmsg ------------------------------ Zero Value CALL test_value (-1, pmsg); pmsg ------------------------------ Negative Value 498

499 SET Statements Set statements are used to set values for both declared variables and parameters. The format of theset statement is: SET A = B; Either A or B may be declared variables. Either A or B may be INOUT parameters. A cannot be an IN parameter. B cannot be an OUT parameter. Examples: Assume the following procedure: CREATE PROCEDURE test_set (IN a INT, INOUT b INT, OUT c INT) BEGIN DECLARE d INTEGER; SET a = b; (invalid - a is IN) SET b = c + 1; (invalid - c is OUT) SET d = b + c; (invalid - c is OUT) SET b = a; (valid) SET b = b + 1; (valid) SET c = b + a; (valid) SET d = b + a; (valid) 499

500 CALL Argument Options Stored procedures are invoked by a CALL statement. Arguments required by the procedure are specified as part of the CALL statement. Arguments correspond to the parameters defined in the procedure, and may be defined using expressions involving constants, variables, or both. CREATE PROCEDURE call_test1 (IN V1 INTEGER, INOUT V2 INTEGER, OUT V3 INTEGER) BEGIN SET V3 = V1 + 2; SET V2 = V2 * V2; END; CALL call_test1 (3,4,V3); 4 V3 ------ ------- 16 5 CALL call_test1 (3+2, 5*3, V3); (5*3) V3 ------ ------- 225 7 500

501 CASTing CALL Arguments CALL arguments may be CAST to acquire any of the following attributes: Data type FORMAT TITLE NAMED Examples: CALL call_test1 (10, CAST(5 AS TITLE 'INOUT Output'), CAST(V3 AS CHAR(4))); CALL call_test1 (10, CAST(5 AS FORMAT '99.99'), CAST(V3 AS NAMED V3_Output)); Nulls may be used as arguments. The keyword NULL may be used or uninitialized argument may be specified. Examples: CALL call_test1 (3,NULL,V3); CALL call_test1 (3,V2,V3); /* V2 Doesn't exist */ 501

502 Using Host Variables As Arguments Argument values may be obtained from a data file. The USING clause of SQL provides a mechanism for importing data values from an external file into host variables. Host variables are defined as variables which contain data from a source external from the client request. Typically, this is an external file whose values are used in parameterized SQL statements. Host variables are recognized by the colon which precedes them. Consider the following section of a BTEQ script using a CALL with parameters supplied from an external file..IMPORT DATA FILE = xyz; /* Designates the external file */.REPEAT *; /* Repeat next command until no more data */ /* Read a host record, and invoke procedure */ USING (a INT, b INT) CALL call_test_1 (:a, :b, V3); Note - This facility is not available to ODBC Clients 502

503 Procedures CALLing Procedures Procedures can CALL other procedures and passing and receiving of argument values between procedures is permitted. REPLACE PROCEDURE test_call6 (IN w1 INTEGER, OUT w2 INTEGER) BEGIN SET w2 = 100/w1 + 100; END; REPLACE PROCEDURE test_call5 (IN v1 INTEGER, OUT v2 INTEGER) BEGIN DECLARE a INTEGER; SET a = v1 + 2; CALL test_call6 (:a,:v2); END; CALL test_call5 (2, v2); v2 -------- 125 If error occurs in the called procedure, of both called and calling procedures are terminated. CALL test_call5 (-2, v2); *** Failure 2618 test_call6:Invalid calculation: division by zero. 503

504 Procedures CALLing Procedures (..cont'd) Objects referenced by a procedure MUST EXIST when the procedure is created. Example: Assume test_call6 has not yet been created. The called procedure must be created before the calling procedure, otherwise an error results as seen here..compile file=test_call5; Error 5495 Stored Procedure test_call6 does not exist. 5495 ; 504

505 Procedures Calling Procedures With Differing Numbers Of Parameters test_call2 requires 2 parameters REPLACE PROCEDURE test_call2 (IN w1 INTEGER, OUT w2 INTEGER) BEGIN SET w2 = w1 + 100; END; test_call4 requires 3 parameters REPLACE PROCEDURE test_call4 (IN v1 INTEGER, OUT v2 INTEGER, OUT v3 INTEGER) BEGIN SET v2 = v1 + 2; CALL test_call2(:v2,:v3); END; CALL test_call4 (3, v2, v3); v2 v3 ---- 5 105 505

506 Other Considerations For CALL Statements Stored procedures are callable only on the platform where they were created (Unix vs. Windows). Stored procedures may not CALL themselves. CALLs can only be performed in ANSI or Teradata mode – not Two Phase Commit mode. CALLs can only be executed by using the session mode in which the procedure was created (ANSI vs. Teradata). A CALL statement must be the only statement inside a macro. A CALL statement may not be part of a multi-statement request. Number of nested CALL statements is limited to 15. 506

507 Stored Procedures Containing SQL Example: The following stored procedure inserts rows into a table while a condition persists. CREATE PROCEDURE sp_log (INOUT p1 INTEGER) BEGIN Label_One: WHILE p1 > 0 DO SET p1 = p1 - 1; IF p1 > 5 THEN ITERATE Label_One; END IF; INSERT logtable (:p1); END WHILE Label_One; END; 507

508 CALL Example 1 CREATE PROCEDURE sp_log (INOUT p1 INTEGER) BEGIN Label_One: WHILE p1 > 0 DO SET p1 = p1 - 1; IF p1 > 5 THEN ITERATE Label_One; END IF; INSERT logtable (:p1); END WHILE Label_One; END; Example: Executing the procedure with a parameter value greater than 5 CALL sp_log (10); Results: 10 ---- 0 SELECT * FROM logtable ORDER BY 1; x ---- 0 1 2 3 4 5 508

509 CALL Example 2 CREATE PROCEDURE sp_log (INOUT p1 INTEGER) BEGIN Label_One: WHILE p1 > 0 DO SET p1 = p1 - 1; IF p1 > 5 THEN ITERATE Label_One; END IF; INSERT logtable (:p1); END WHILE Label_One; END; Example: Executing the procedure with a parameter value greater than 5 CALL sp_log (3); Results: 3 ---- 0 SELECT * FROM logtable ORDER BY 1; x ---- 0 1 2 509

510 Stored Procedure Rights and Permissions New Stored Procedures: To create a new procedure, you need the CREATE PROCEDURE privilege on the containing database. The creator must have appropriate privileges on database objects referenced by the procedure. Existing Stored Procedures: To modify or change an existing procedure, you need the DROP PROCEDURE privilege on the containing database, or on the procedure object. To invoke a stored procedure, you need EXECUTE PROCEDURE privilege. 510

511 Using The LOOP Statement A LOOP statement defines a repetitive programming sequence. A label may optionally be used to define a loop. A LEAVE statement permits a programmed exit from the loop, otherwise a loop is considered infinite. An exception condition terminates the loop and the stored procedure unless a condition handler is defined. A DECLARE statement is used to declare a local variable, data type and optionally a default value. Example: Create a looping procedure that inserts rows into a log table. CREATE PROCEDURE sp_loop ( ) BEGIN DECLARE vcount INTEGER DEFAULT 0; loop_label: LOOP SET vcount = vcount + 1; IF vcount > 5 THEN LEAVE loop_label; END IF; INSERT logtable (:vcount); END LOOP loop_label; END; This procedure has no parameters. To execute this procedure: CALL sp_loop( ); 511

512 Declaring Cursors A cursor is necessary in a stored procedure when an SQL statement is expected to return multiple data rows. The cursor enables processing of the returned answer set one row at a time. FOR loopvar AS cur1 CURSOR FOR SELECT employee_number, department_number FROM employee DO PRINT 'EmpNo:', loopvar.employee_number; END FOR; FOR statement declares a cursor. It assigns a cursor name of 'cur1'. It assigns a 'loop' name of 'loopvar'. Contd.. 512

513 SELECT statement returns multiple rows. DO statement defines what will occur for each row returned. PRINT statement prints to the database window. It is used for debugging stored procedures and otherwise is not typically used. Column names must be qualified with the 'loop' name when referenced in the procedure. (i.e. loopvar.employee_number) END FOR defines the lower boundary of the FOR loop. 513

514 Cursor Example REPLACE PROCEDURE sp_cur5 (OUT prowcount INTEGER) BEGIN DECLARE newvar BYTEINT DEFAULT 0; FOR loopvar AS cur1 CURSOR FOR SELECT employee_number AS emp, department_number AS dept FROM employee WHERE employee_number < 1005 ORDER BY 1 DO SET newvar = newvar + 1; PRINT 'Row Count:', newvar, 'EmpNo:', loopvar.emp; END FOR; SET prowcount = newvar; END; Contd.. 514

515 Syntax rules : END FOR statements must be terminated with a semicolon. The SQL statement is not terminated with a semi-colon because it is part of a cursor declaration. Multi-statement requests are not valid with cursors – only a single SQL statement is permitted. To execute the procedure: CALL sp_cur5(prowcount); prowcount ----------- 5 515

516 Viewing PRINT Output PRINT Output can be reviewed via the database window (window #5). This requires the privilege to run the console utility. On UNIX systems, assuming you have this privilege, the database window can be seen by entering the command: cnsterm 5 Results: PED1 | 0 1251 | PED1.SP_CUR5 | 9 : 2000-06-19 22:33:37.760000-03:00| Row Count: 1 EmpNo: 801 PED1 | 0 1251 | PED1.SP_CUR5 | 9 : 2000-06-19 23:33:37.780000-03:00| Row Count: 2 EmpNo: 1001 PED1 | 0 1251 | PED1.SP_CUR5 | 9 : 2000-06-20 00:34:37.800000-03:00| Row Count: 3 EmpNo: 1002 PED1 | 0 1251 | PED1.SP_CUR5 | 9 : 2000-06-20 01:35:37.830000-03:00| Row Count: 4 EmpNo: 1003 PED1 | 0 1251 | PED1.SP_CUR5 | 9 : 2000-06-20 02:36:37.860000-03:00| Row Count: 5 EmpNo: 1004 Key: User name - (PED1) Session id - (01251) Procedure name - (SP_CUR5) Line number of PRINT statement - (9) Timestamp - (2000-06-20 02:36:37.860000-03:00) User specified string - (Row Count: 5 EmpNo: 1004) The PRINT statement can be a useful tool for debugging of stored procedures. 516

517 Using ACTIVITY_COUNT REPLACE PROCEDURE sp_cur5a (OUT prowcount INTEGER) BEGIN FOR loopvar AS cur1 CURSOR FOR SELECT employee_number AS emp, department_number AS dept FROM employee WHERE employee_number < 1005 ORDER BY 1 DO PRINT 'Row Count:', ACTIVITY_COUNT, 'EmpNo:', loopvar.emp; END FOR; SET prowcount = ACTIVITY_COUNT; END; The ACTIVITY_COUNT system variable is set at any given time to a value representing the number of rows processed by the SQL statement in the procedure up to that point. 517

518 Compiling Stored Procedures Stored procedures must be compiled by an SPL compiler which resides on the server side and requires the use of a C compiler. The resulting output from the compiler and, optionally, the source code, are stored in a 'table' on the user's database. In BTEQ, the command for compilation is as follows:.COMPILE FILE = sp_source; Either syntax errors are returned, or a message advising that the procedure has been created.By default, source code is saved as part of the compilation output. If it is not desired to save the source on the server, this may be accomplished by the following compilation command:.COMPILE FILE = sp_source WITH NOSPL; Note that if you do not save the SPL source, the SHOW PROCEDURE command is unable to return your source code. If your procedure source contains a PRINT statement, it can be enabled by compiling with the following compilation command:.COMPILE FILE = sp_source WITH PRINT; The default is to leave PRINT statements disabled. 518

519 Compiling and Permissions Creating Stored Procedures Successfull compile a stored procedure depends on: - syntax of the SPL and SQL statements - access rights of the creator must be checked against the referenced database objects. Calling Stored Procedures Invoking a stored procedure requires EXECUTE PROCEDURE privilege either on the stored procedure oron the database containing it Assuming a stored procedure compiles successfully, it does not logically follow that the execution of the procedure will also be successful. Any of the following events may have occurred between the time of the compile and the time of the execution: - Permissions may have been revoked on tables, views or databases. - Columns may have been dropped from tables or views. - Tables, views or databases may have been dropped Additionally, execution errors may occur which were not detectable at compile time (i.e. division by zero) 519

520 Compiling Procedures in ODBC and JDBC When creating stored procedures using ODBC or JDBC clients, the compile is done automatically as part of the CREATE PROCEDURE processing. The user can simply submit a CREATE PROCEDURE statement and if creation is successful, he/she may execute the procedure directly. In BTEQ, the user must submit an explicit compile step. Compile Time Options - cannot be specified as part of the CREATE PROCEDURE statement. In ODBC, for example, these options are set by the ODBC Administrator Program as follows: ProcedureWithPrintStmt (N/P) ProcedureWithSPLSource (Y/N) The default values are: ProcedureWithPrintStmt=N ProcedureWithSPLSource=Y These options cannot be overridden at the user level. If a different option is desired, it must be implemented by the ODBC Administrator Program. Note: Queryman 5.1.0 is the minimum level needed for this ODBC client to support stored procedures. 520

521 SELECT INTO - Returning A Single Row The SELECT INTO syntax is designed for the return of a single data row. A cursor is not necessary when the result set consists of only a single row. REPLACE PROCEDURE sel_into (IN empno INTEGER, OUT deptnum INTEGER, OUT lastnm CHAR(20)) BEGIN SELECT department_number, last_name INTO :deptnum, :lastnm FROM employee WHERE employee_number = :empno; END; Contd.. 521

522 Rules for SELECT INTO: INOUT and OUT parameters may be used as INTO variables (Declared Variables may also be used). IN and INOUT parameters may be used as WHERE clause variables (Declared Variables may also be used). INTO and WHERE clause variables are defined as host variables, meaning they are preceded with a colon. The SQL statement is terminated with a semicolon because it is not part of a cursor declaration. Contd.. SELECT INTO - Returning A Single Row (..Cont'd) 522

523 SELECT INTO - Returning A Single Row (..Cont'd) Execute the procedure: CALL sel_into (1008,deptnum,lastnm); Results: deptnum lastnm ------- 301 Kanieski If no row is returned, both output arguments are returned with nulls. Attempting to return multiple rows with a SELECT INTO will return an error. *** Failure 7627 sel_many_into:SELECT-INTO returned more than one row. 523

524 Exceptions Cause Procedure Exit By default, when an exception occurs in a procedure, the procedure call is terminated. REPLACE PROCEDURE sel_many_into_2 (IN deptnum INTEGER, OUT lastnm CHAR(20)) BEGIN SELECT last_name INTO :lastnm FROM employee WHERE department_number = :deptnum; PRINT 'Successful Completion'; END; CALL sel_many_into_2(501,lastnm); ** Failure 7627 sel_many_into_2:SELECT-INTO returned more than one row. (PRINT statement did not execute) NOTE - PRINT statement can only execute if the procedure is compile using the WITH PRINT option. PRINT statements are intended to be used for debugging purposes only. 524

525 Getting HELP On Procedure Definitions The HELP PROCEDURE command is used to return information about the definition of stored procedures. There are two variations of this command: HELP PROCEDURE procedurename HELP PROCEDURE procedurename ATTRIBUTES HELP PROCEDURE sel_many_into_2; Parameter Name deptnum (1st Parameter) Type I (Integer) Comment ? (No Comments) Nullable Y (Allows Nulls) Format (10)9 (Default Format) Title ? (No Title) Max Length 4 (Four Bytes Max Length) Decimal Total Digits ? (Not A Decimal) Decimal Fractional Digits ? (Not A Decimal) Range Low ? (No Range) Range High ? (No Range) UpperCase N (Not Defined Uppercase) Table/View? P (Procedure Table Type) Default value ? (Defaults As Null) Char Type 0(Not Character Type) Parameter Type I (IN Type) : : : 525

526 Getting HELP On Procedure Definitions (..cont'd) HELP PROCEDURE sel_many_into_2 ATTRIBUTES; Transaction Semantics TERADATA (Created In Teradata Mode) Print Mode N (Created Without Print Option) Platform UNIX MP-RAS (Created On Unix MP-RAS) Character Set ASCII Default Character DataType LATIN Collation ASCII Text Y (Source SPL Is Stored) 526

527 Module 35 Stored Procedures - Part 2 527

528 After completing this module, a student should see how to: Create transactions involving stored procedures. Create condition handlers to handle exception conditions in stored procedures. Predict the behavior of stored procedures involving transactions and condition handlers. Create stored procedures using updateable cursors and positioned updates and deletes. 528

529 Updateable Cursors With Positioned UPDATEs Updateable Cursors allow 'in place' updates and deletes of rows that have been previously located via an SQL SELECT statement. These are referred to as 'positioned' updates and deletes. Assume that you wish to update employee's salaries to a specified percentage increase depending on the range the salaries fall within. Without updateable cursors, each row is required to be located twice: - first (SELECT) to look at the employee's salary and to determine the appropriate range - second (UPDATE) to award an increase based on range. Whether the row is located via an index or a table scan makes no difference - the row must be located for the SELECT and located again for the UPDATE. Updateable cursors allow you to read the row using a SELECT and to hold the position of the row. The update may then be applied using 'CURRENT OF CURSOR' to correctly target the 'current' row. Because a cursor permits the reading of many rows, each row may be read and optionally updated or deleted, using the current cursor position. 529

530 Updateable Cursors With Positioned UPDATEs(..cont'd) Example: Using a cursor, update the salaries of all employees in a given department. Salary less than $30,000, then increase 10%. Salary between $30,000 and $39,999 then increase 8%. Salary between $40,000 and $49,999 then increase 5%. CREATE PROCEDURE upd_cur1 (IN deptnum INT) BEGIN DECLARE salary DEC(7,2); FOR for_loop AS cursor1 CURSOR FOR SELECT employee_number, salary_amount FROM employee WHERE department_number = :deptnum DO SET salary = for_loop.salary_amount; IF salary < 30000 THEN UPDATE employee SET salary_amount = :salary * 1.10 WHERE CURRENT OF cursor1; ELSEIF salary < 40000 THEN UPDATE employee SET salary_amount = :salary * 1.08 WHERE CURRENT OF cursor1; ELSEIF salary < 50000 THEN UPDATE employee SET salary_amount = :salary * 1.05 WHERE CURRENT OF cursor1; END IF; END FOR; END; 530

531 Updateable Cursors With Positioned DELETEs Positioned DELETEs may also be accomplished with an updateable cursor. Example: Give a 10% budget increase to any department whose current budget is under $500,000. Give a 5% budget increase to any department whose budget is under $1,000,000. Delete any department whose budget is either zero or null. CREATE PROCEDURE upd_cur2 ( ) BEGIN DECLARE budget DECIMAL(10,2); FOR for_loop AS cursor2 CURSOR FOR SELECT COALESCE(budget_amount,0) AS bud_amt FROM department DO SET budget = for_loop.bud_amt; IF budget = 0 THEN DELETE FROM department WHERE CURRENT OF cursor2; ELSEIF budget < 500000 THEN UPDATE department SET budget_amount = budget_amount*1.10 WHERE CURRENT OF cursor2; ELSEIF budget < 1000000 THEN UPDATE department SET budget_amount = budget_amount*1.05 WHERE CURRENT OF cursor2; END IF; END FOR; END; 531

532 Other Facts About Updateable Cursors Updateable cursors are governed by the following rules: They can only be created and executed in an ANSImode session. Multiple updates of the currently positioned row are allowed. Multiple updates followed by a delete of the currently positioned row are allowed. They cannot be implemented against tables for which triggers have been defined. 532

533 Condition Handlers Condition handlers are coding constructs which perform one or more actions depending on the type of exception encountered. The absence of condition handlers in a stored procedure indicates that the procedure will terminate at the exception point when an exception occurs. Condition handlers are added to the beginning of the stored procedure using DECLARE HANDLER syntax. There are two types of condition handlers: EXIT handlers - These cause the called procedure to terminate execution after performing the handler actions. CONTINUE handlers - These cause the procedure to continue execution following the statement that caused the exception, after the handler actions are performed. Two reserved words are defined to allow the handler to choose when to process an exception: SQLSTATE - Permits the handler to process for exceptions which return specific exception codes. SQLEXCEPTION - Tells the handler to process all exceptions not handled by specific SQLSTATE handlers. 533

534 Condition Handlers (..Cont'd) Example: Code an exit handler which logs a row into a logtable REPLACE PROCEDURE handler_2 (IN deptnum INTEGER, OUT lastnm CHAR(20)) BEGIN DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN PRINT 'EXCEPTION CONDITION OCCURRED'; INSERT INTO error_log VALUES (:SQLCODE, :SQLSTATE, CURRENT_TIME); END; SELECT last_name INTO :lastnm FROM employee WHERE department_number = :deptnum; PRINT 'Successful Completion'; END; 534

535 Executing an EXIT Condition Handler REPLACE PROCEDURE handler_2 (IN deptnum INTEGER, OUT lastnm CHAR(20)) BEGIN DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN PRINT 'EXCEPTION CONDITION OCCURRED'; INSERT INTO error_log VALUES (:SQLCODE, :SQLSTATE, CURRENT_TIME); END; SELECT last_name INTO :lastnm FROM employee WHERE department_number = :deptnum; PRINT 'Successful Completion'; END; CALL handler_2(301,lastnm); lastnm ------------- ? sel * from error_log; Sql_code Sql_State time_of_day ------------- --------------- ----------------- 7627 21000 15:52:10 SELECT fails(multiple rows) EXIT HANDLER activates Procedure terminates without running the PRINT 'Success..' message 535

536 Executing a CONTINUE Condition Handler Now consider the same procedure using a CONTINUE handler: REPLACE PROCEDURE handler_2 (IN deptnum INTEGER, OUT lastnm CHAR(20)) BEGIN DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN PRINT 'EXCEPTION CONDITION OCCURRED'; INSERT INTO error_log VALUES (:SQLCODE, :SQLSTATE, CURRENT_TIME); END; SELECT last_name INTO :lastnm FROM employee WHERE department_number = :deptnum; PRINT 'Successful Completion'; END; 536

537 Executing a CONTINUE Condition Handler(..cont'd) CALL handler_2(301,lastnm); lastnm ------------- ? sel * from error_log; Sql_code Sql_State time_of_day ------------- --------------- ----------------- 7627 21000 15:52:10 SELECT fails CONTINUE HANDLER activates Procedure continues on and runs the PRINT 'Success..' message Note that the reserved word SQLCODE contains the Teradata error code (7627) associated with this exception. SQLSTATE is an ANSI standard exception code defined as CHAR(5). A mapping of Teradata error codes to SQLSTATE permits errors to be tracked by either method. Condition handlers may only be tested for SQLSTATE, not SQLCODE. Following successful completion of the condition handler actions, all three system variables are reset as follows: SQLSTATE = '00000' SQLCODE = 0 ACTIVITY_COUNT = 0 537

538 Multiple Handlers Multiple exception handlers are permitted: Example: Provide an EXIT handler specifically for the error 21000, and also for error 42000. For any other errors, allow the procedure to CONTINUE with a warning message. REPLACE PROCEDURE handler_2 (IN deptnum INTEGER, OUT lastnm CHAR(20)) BEGIN DECLARE EXIT HANDLER FOR SQLSTATE '21000', SQLSTATE '42000' BEGIN PRINT 'ERROR - EXCEPTION OCCURRED'; INSERT INTO error_log VALUES (:SQLCODE, :SQLSTATE, CURRENT_TIME); END; DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN PRINT 'WARNING - EXCEPTION OCCURRED' ; INSERT INTO error_log VALUES (:SQLCODE, :SQLSTATE, CURRENT_TIME); END; SELECT last_name INTO :lastnm FROM employee WHERE department_number = :deptnum; PRINT 'Successful Completion'; END; 538

539 Multiple Handlers (..cont'd) Occurrences of SQLSTATES 21000 and 42000 are handled by the EXIT handler. Any other exceptions are handled by the CONTINUE handler. A single condition handler may not combine both specific SQLSTATEs and SQLEXCEPTION in the FOR clause Execute the procedure. CALL handler_4(501,lastnm); lastnm ------ ? Review the database window. cnsterm 5 PED1 | 0 1258 | PED1.HANDLER_4 | 5 : 2000-06-27 00:00:39.050000-00:00|ERROR - EXCEPTION OCCURRED Check the error log. SELECT * FROM error_log; Sql_Code Sql_State time_of_day ------- --------- ---------- 7627 21000 13:56:58 539

540 Stored Procedures and ANSI Mode Transactions Procedures may be created in either an ANSI-mode session or a Teradata-mode session. The procedure must be executed within the same session-mode as its creation. In ANSI mode, the first SQL statement submitted from the stored procedure opens a transaction. If subsequent SQL statements are submitted, the transaction continues untilone of the following is encountered: COMMIT - Terminate the transaction and commit the changes to the database. ABORT - Terminate the transaction and rollback any changes since the transaction began. ROLLBACK - Same as ABORT SQL Statement Failure - same as ABORT Three other possible occurrences which allow the transaction to continue: SQL Statement Success - The current SQL statement completes successfully and the transaction continues. SQL Statement Error- The current SQL statement aborts and the transaction continues SQL Statement Warning - The current SQL statement completes with a warning message and the transaction continues. In ANSI mode, when an SQL statement does not complete successfully, either an error or a failure condition has occurred. How the condition is handled depends on which type it is. 540

541 Stored Procedures and ANSI Mode Transactions (..cont'd) Four possible outcomes of an SQL statement in ANSI mode: Success condition: SQL has successfully completed. SQLSTATE = '00000'. ACTIVITY_COUNT = # rows affected. > Transaction continues. Warning condition: SQL has completed with a warning message. SQLSTATE > '00000'. ACTIVITY_COUNT = # rows affected. > Transaction continues. Error Condition: SQL has encountered an error condition. SQLSTATE > '00000'. Request is rolled back. > Transaction continues Failure Condition: One of the following conditions has occurred: 1.A deadlock condition has been detected. 2.A DDL statement has aborted. 3.An explicit ROLLBACK or ABORT statement was encountered. SQLSTATE > '00000'. > Transaction is rolled back and ended. 541

542 ANSI Mode Transaction Examples Consider a stored procedure 'Proc_1' created in ANSI mode, which consists of three UPDATE macros - UPD1, UPD2, UPD3 - followed by a COMMIT statement. Assume that a CONTINUE handler also exists to allow the procedure to run to completion. CREATE PROCEDURE Proc1( ) BEGIN DECLARE CONTINUE HANDLER FOR SQLEXCEPTION UPDATE t1 SET col_a=col_a/2; /* UPD1 */ UPDATE t2 SET col_b=col_b/3; /* UPD2 */ UPDATE t3 SET col_c=col_c/4; /* UPD3 */ COMMIT; END; Assume an ANSI error condition occurs in UPD2. Recall that in ANSI mode, an error condition causes the statement to rollback but allows the transaction to continue. Contd.. 542

543 Procedure Execution(With CONTINUE handler) UPD1 - executes successfully UPD2 - error condition - references table which has been removed - statement is rolled back UPD3 - executes successfully COMMIT - UPD1 and UPD3 are committed Results of Procedure Execution UPD1 - committed UPD2 - rolled back UPD3 - committed 543

544 ANSI Mode Transaction Examples (cont'd) Assume an ANSI failure condition occurs in UPD2. Procedure Execution (With CONTINUE handler) UPD1 - executes successfully UPD2 - failure condition, a deadlock situation is encountered - transaction rollback is initiated UPD3 - starts new transaction - executes successfully COMMIT - UPD3 is committed Results of Procedure Execution UPD1 - rolled back UPD2 - rolled back UPD3 - committed 544

545 Stored Procedures and Teradata Mode (BTET) Transactions In Teradata (BTET) mode, each SQL statement submitted from a stored procedure represents a transaction. If several SQL statements are submitted as a single transaction, BEGIN and END TRANSACTION protocols must be used to define the transaction boundaries. This is called an 'explicit' transaction. An explicit transaction continues until one of the following occurs: END TRANSACTION - Terminates the transaction and commit the changes to the database. ABORT - Terminate the transaction and rollback any changes since the transaction began. ROLLBACK - Same as ABORT SQL Statement Failure - Same as ABORT In Teradata mode, no distinction is made between error and failure conditions. There are two other possible occurrences which allows the transaction to continue: SQL Statement Success - The current SQL statement completes successfully and the transaction continues. SQL Statement Warning - The current SQL statement completes with a warning message and the transaction continues. 545

546 Stored Procedures and Teradata Mode (BTET) Transactions (cont'd) Three possible outcomes of an SQL statement in BTET mode: Success condition: SQL has successfully completed. SQLSTATE = '00000'. ACTIVITY_COUNT = # rows affected. > Transaction continues. Warning condition: SQL has completed with a warning message SQLSTATE > '00000'. ACTIVITY_COUNT = # rows affected. > Transaction continues. Error or Failure Condition: SQL has encountered an error or failure condition. SQLSTATE > '00000'. > Transaction is rolled back and ended. 546

547 Teradata Mode Transaction Examples CREATE PROCEDURE Proc_1 ( ) BEGIN DECLARE CONTINUE HANDLER FOR SQLEXCEPTION UPDATE t1 SET col_a=col_a/2; /* UPD1 */ UPDATE t2 SET col_b=col_b/3; /* UPD2 */ UPDATE t3 SET col_c=col_c/4; /* UPD3 */ COMMIT; END; Assume a Failure condition in UPD2 (implicit transactions) Procedure Execution(With CONTINUE handler) UPD1 - executes successfully UPD2 - error/failure condition references a table that has been dropped - statement is rolled back UPD3 - executes successfully Results of Procedure Execution UPD2 - is rolled back as a stand-alone transaction (each SQL statement is a transaction) UPD1 - committed UPD3 - committed 547

548 Teradata Mode Transaction Examples (..cont'd) Assume explicit BT or ET are included in the procedure body. Assume Failure condition - explicit transactions) Procedure Execution (With CONTINUE handler) BT - transaction begins UPD1 - executes successfully UPD2 - error/failure condition a deadlock situation is encountered - transaction rollback is inititated UPD3 - executes successfully ET - transaction committed Results of Procedure Execution UPD1 - rolled back UPD2 - rolled back UPD3 - committed ANSI mode permits the following SQL commands: COMMIT ABORT ROLLBACK Teradata mode permits the following SQL commands: BEGIN TRANSACTION or BT END TRANSACTION or ET ABORT ROLLBACK 548

549 Condition Handler Exceptions (ANSI-mode) Exception occurring in the procedure main body will either cause the procedure to terminate, or will activate a condition handler if one is defined for the particular exception. An exception may also occur within the condition handler itself. In this section, we will consider which path the transaction takes depending on where the failure occurs. Example: A procedure 'Sp_1' consisting of several UPDATE macros and a CONTINUE handler as follows: CREATE PROCEDURE Sp_1 ( ) BEGIN DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN UPDATE t3 SET col_c=col_c/4; /* UPD3 */ END; UPDATE t4 SET col_d=col_d/2; /* UPD4 */ UPDATE t5 SET col_e=col_e/3; /* UPD5 */ UPDATE t6 SET col_f=col_f/4; /* UPD6 */ END; 549

550 Condition Handler Exceptions (ANSI-mode) (..cont'd) Example 1 (error condition in procedure body) Assume: The procedure is created / executed in ANSI mode. An ANSI error condition occurs in UPD5. Recall that in ANSI mode, an error condition causes the statement to rollback but allows the transaction to continue. CALL Sp_1 ( ) ; /* ANSI mode*/ COMMIT; Procedure Execution UPD4 - executes successfully UPD5 - error 42000 reported for UPD5 - request is rolled back - condition handler activated UPD3 - executes successfully - CONTINUE handler returns control to main procedure UPD6 - executes successfully COMMIT - all changes are committed except UPD5 Transactions will remain uncommitted until a COMMIT or ROLLBACK statement is encountered in ANSI mode. 550

551 Condition Handler Exceptions (ANSI-mode) (..cont'd) Example 2 (error conditions in procedure body and in handler) Assume: The procedure is created/executed in ANSI mode. An error condition occurs in UPD5. An error also occurs in the condition handler request UPD3. CALL Sp_1 ( ); /* ANSI mode*/ COMMIT; Procedure Execution UPD4 - executes successfully UPD5 - error 42000 reported for UPD5 - request is rolled back - condition handler is activated UPD3 - error 53015 occurs for UPD3 - procedure is terminated, UPD6 - never executes COMMIT - Commits UPD4 only Results of Procedure Execution UPD5 - error code 42000 reported Note that when an exception occurs in a condition handler, the procedure will terminate, even if there is a condition handler defined to handle this exception. 551

552 Condition Handler Exceptions (Teradata-mode) Example 1 (failure conditions in both procedure body and handler) Assume: The procedure is created/ executed in Teradata mode. A Teradata failure condition occurs in UPD5. A failure also occurs in the condition handler request UPD3. Recall that in Teradata mode, a failure condition causes the current transaction to rollback. In this example, each individual request is treated as a separate transaction. CALL Sp_1 ( ); /* Teradata mode*/ Procedure Execution UPD4 - executes successfully and commits UPD5 - error 42000 reported for UPD5 - condition handler is activated UPD3 - error 53015 occurs for UPD3 - procedure is terminated UPD6 - never executes Results of Procedure Execution UPD5 - error code 42000 reported 552

553 Condition Handler Exceptions (Teradata-mode) (..cont'd) Example 2 (same failures - explicit transaction) Assume the same conditions, however the procedure execution is defined as an explicit transaction. In this case, all requests are rolled back. BT; CALL Sp_1 ( ); ET; Procedure Execution UPD4 - executes successfully UPD5 - error 42000 reported for UPD5 - condition handler is activated UPD3 - error 53015 occurs for UPD3 - procedure is terminated UPD6 - never executes Results of Procedure Execution UPD4 - is rolled back as part of transaction rollback UPD5 - error code 42000 reported 553

554 Transactions Containing Stored Procedures (ANSI-mode) In addition to embedding transactions within a stored procedure, a stored procedure itself may be part of a larger transaction. In addition, the stored procedure may have condition handlers. A request failure may occur in any one of these three locations within the transaction: outside the stored procedure within the stored procedure main body within a condition handler This section will consider the various paths the transaction will take depending on where the failure occurs. (Repeated for convenience) CREATE PROCEDURE Sp_1 ( ) BEGIN DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN UPDATE t3 SET col_c=col_c/4; /* UPD3 */ END; UPDATE t4 SET col_d=col_d/2; /* UPD4 */ UPDATE t5 SET col_e=col_e/3; /* UPD5 */ UPDATE t6 SET col_f=col_f/4; /* UPD6 */ END; 554

555 Transactions Containing Stored Procedures (ANSI-mode) (..cont'd) Example 1 (Error Condition - ANSI-mode) Assume: The procedure is created and executed in ANSI mode. An ANSI error condition occurs in UPD5. UPD1 and UPD2 are macros that are executed outsideof the stored procedure. Recall that in ANSI mode, an error condition causes the statement to rollback, but allows transaction to continue. UPDATE t1 SET col_a = col_a/2; /* UPD1 */ UPDATE t2 SET col_b = col_b/3; /* UPD2 */ CALL Sp_1 ( ); COMMIT; Procedure Execution UPD1 - executes successfully UPD2 - executes successfully UPD4 - executes successfully UPD5 - error condition reported - UPD5 rolled back - handler is activated UPD3 - executes successfully - CONTINUE handler returns control to main procedure UPD6 - executes successfully COMMIT - UPD1, UPD2, UPD4, UPD3, UPD6 are committed 555

556 Transactions Containing Stored Procedures (ANSI-mode) (..cont'd) Example 2 (Failure Condition - ANSI-mode) Assume the following: The procedure is created and executed in BTEQANSI mode. An ANSI failure condition occurs in UPD5. UPDATE t1 SET col_a = col_a/2; /* UPD1 */ UPDATE t2 SET col_b = col_b/3; /* UPD2 */ CALL Sp_1 ( ); COMMIT; Procedure Execution UPD1 - executes successfully UPD2 - executes successfully UPD4 - executes successfully UPD5 - failure condition reported - UPD5, UPD4, UPD2, UPD1 rolled back - handler is activated UPD3 - executes successfully - CONTINUE handler returns control to main procedure UPD6 - executes successfully COMMIT - UPD3, UPD6 are committed 556

557 Transactions Containing Stored Procedures (Teradata-mode) Recall that in Teradata mode, each separate request is a stand-alone transaction. A failure condition affects only that request. In Teradata mode, there is no distinction between error and failure conditions. Both are handled the same. Example 1 (Teradata Failure Condition) Assume: The procedure is created/executed in Teradata mode. A Teradata failure condition occurs in UPD5. UPDATE t1 SET col_a = col_a/2; /* UPD1 */ UPDATE t2 SET col_b = col_b/3; /* UPD2 */ CALL Sp_1 ( ); Procedure Execution UPD1 - executes successfully and commits UPD2 - executes successfully and commits UPD4 - executes successfully and commits UPD5 - failure condition reported - UPD5 rolled back - handler is activated UPD3 - executes successfully and commits - CONTINUE handler returns to main procedure UPD6 - executes successfully and commits 557

558 Transactions Containing Stored Procedures (Teradata-mode) (..cont'd) Example 2 (Teradata Failure in explicit transaction) Assume: The procedure is created/executed in Teradata mode. A Teradata failure condition occurs in UPD5. BT and ET are used to define transaction boundaries. BT; UPDATE t1 SET col_a = col_a/2; /* UPD1 */ UPDATE t2 SET col_b = col_b/3; /* UPD2 */ CALL Sp_1 ( ); ET; Procedure Execution BT - initiates explicit transaction UPD1 - executes successfully UPD2 - executes successfully UPD4 - executes successfully UPD5 - failure condition reported - UPD5, UPD4, UPD2, UPD1 are rolled back - handler is activated - explicit transaction is ended UPD3 - executes successfully and commits (new transaction) - CONTINUE handler returns to main procedure UPD6 - executes successfully and commits (new transaction) ET – ignored In this case, the failure of UPD5 rolled back the transaction to the BT boundary. Because this ends the transaction, the next two requests are treated, by default, as individual transactions. The ET, when encountered, is ignored. 558

559 Module 36 Advanced Aggregate Functions 559

560 After completing this module, a student should be able to recognize the new aggregate functions implemented in V2R4. 560

561 AGGREGATE Functions New AGGREGATE Statistical Functions for use in SQL Unary statistical functions: (requires single argument) STDDEV_SAMP STTDEV_POP VAR_SAMP VAR_POP SKEW KURTOSIS Binary statistical functions: (requires two arguments) CORR COVAR_POP REGR_SLOPE REGR_INTERCEPT Common attributes of all AGGREGATE statistical functions: They may be used with GROUP BY syntax to produce group based function output. They may be combined with standard aggregate functions in a SELECT. They may not be combined with OLAP Windowing functions in a SELECT, QUALIFY or ORDER BY clause. 561

562 Standard Deviation Functions STDDEV_SAMP ({DISTINCT} value_expression) Value_expression is a column expression whose sample standard deviation is to be computed. Returns the sample standard deviation for the non-null data points in value_expression. Is the measure of dispersion from the mean of the given sample. STDDEV_POP ({DISTINCT} value_expression) Value_expression is a column expression whose population standard deviation is to be computed. Returns the population standard deviation for the non-null data points in value_expression. Is the measure of dispersion from the mean of the given population. 562

563 Variance Functions VARSAMP ({DISTINCT} value_expression) Value_expression is a column expression whose sample variance is to be computed. Returns the sample variance for the data points in value_expression. Is a measure of dispersion from the mean of that sample or the square of the sample standard dev. VAR_POP ({DISTINCT} value_expression) Value_expression is a column expression whose population variance is to be computed. Returns the population variance for the data points in value_expression. Is a measure of dispersion from the mean of that population. 563

564 Distribution Functions SKEW ({DISTINCT} value_expression) Value_expression is a column expression for which theskewness of the distribution of its values is to be computed. Returns the skewness of the distribution of value_expression. Is the measure of the asymmetry of the distribution about its mean compared with the normal distribution (i.e. skewness of 0). Positive skewness indicates asymmetry extending toward more positive values. Negative skewness indicates asymmetry extending toward more negative values. KURTOSIS ({DISTINCT} value_expression) Value_expression is a column expression for which the kurtosis of the distribution of its values is to be computed. Returns the kurtosis of the distribution of value_expression. Is the measure of the relative peakedness or flatness of the distribution compared with the normal distribution (i.e. kurtosis of 0). Positive skewness indicates a relative peakedness of the distribution. Negative skewness indicates a relative flatness of the distribution 564

565 Correlation And Covariance Functions COVAR_POP (value_expression, value_expression) Value_expression is a column expression to be paired with a second column expression to determine their covariance. Returns the covariance of its arguments for all non-null data point pairs. Is the average of the deviation products for each non-null data point pair. CORR (value_expression, value_expression) Value_expression is a column expression to be correlated with a second column expression. Returns the Pearson product moment correlation coefficient of its arguments for all non-null data points. Is the measure of the non-causal linear association between variables. 565

566 Linear Regression Functions REG_SLOPE (value_expr1, value_expr2) Value_expr1 - independent variable for theregression. Value_expr2 - dependent variable for theregression. Returns the slope of the linear regression line through all non-null data pairs on its dependent and independent variable arguments. Is the measure of the rate of change of the regression of one independent variable on the dependent variable. REG_INTERCEPT (value_expr1, value_expr2) Value_expr1 - independent variable for the regression. Value_expr2 - dependent variable for the regression. Returns the intercept of the linear regression line through all non-null data pairs on its dependent and independent variable arguments. Is the intercept point at which the regression line through the non-null data pairs in the sample intersects the ordinate, or y-axis, of the graph. 566

567 Increased System Limits, Performance, Flexibility Increased System Limits V2R3 V2R4 Number of concurrent users 32KB 4.2 Billion Concrete Step Size 64KB 1MB Explain output text max size 64KB No Limit Max size character string constant 255 32K Number of spool tables per query 512 2048 Number of levels of query nesting 10 64 (Subqueries, derived tables,..) V2R4 performance improvements INSERT/SELECT into empty SET table improvement COLLECT STATISTICS resource reduction Optimizer enhancements Join and covering index enhancements Transient journal overhead reduction Aggregation improvements in path length for large aggregations Derived table distribution improvements SAMPLE performance improvement Merge Delete performance improvement Various platform flexibility extensions: 5200 and V2 BYNET allow 512 nodes Windows 2000 support (NT 5.0) permitting 32 MPPnodes, up to 8TB Concurrent release of consistent RDBMS for MP-RAS and NT 567


Download ppt "MODULE 1 1 Please logon to"

Similar presentations


Ads by Google