Sunteți pe pagina 1din 218

1.

) Introduction to Teradata SQL

Objectives

After completing this module, you should be able to:

 Describe the structure of a Relational Database Management System


(RDBMS).
 Explain the role of Structured Query Language (SQL) in accessing a
Relational Database.
 List the three categories of SQL statements and describe their function.

What is an RDBMS?

Data is organized into tables in a Relational Database Management System


(RDBMS). Rows in the table represent instances of an entity, in this case an
employee or a department. Columns represent the data fields which comprise
the rows. Relations between tables occur when a column in one table also
appears as a column in another.

Here is an example of two related tables:


Can you answer the following questions using the tables above?

Question What is the department name for employee


1: 1004?
[Answer]

Question
Who is the manager of employee 1004? [Answer]
2:

What is SQL?

Structured Query Language (SQL) is the industry standard language for


communicating with Relational Database Management Systems. SQL is used to
look up data in relational tables, create tables, insert data into tables, grant
permissions and many other things.

Structured Query Language is used to define the answer set that is returned
from the Teradata Database.

SQL is a non-procedural language, meaning it contains no procedural-type


statements such as those listed here:

 GO TO
 PERFORM
 DO LOOP
 OPEN FILE
 CLOSE FILE
 END OF FILE

SQL Commands

SQL statements commonly are divided into three categories:

1. Data Definition Language (DDL) - Used to define and create database


objects such as tables, views, macros, databases, and users.
2. Data Manipulation Language (DML) - Used to work with the data,
including such tasks as inserting data rows into a table, updating an
existing row, or performing queries on the data. The focal point of this
course will be on SQL statements in this category.
3. Data Control Language (DCL) - Used for administrative tasks such as
granting and revoking privileges to database objects or controlling
ownership of those objects. DCL statements will not be covered in detail
in this course. For complete Data Control Language coverage, please see
the Teradata Customer Education "Teradata Database Administration"
course.

Data Definition Language (DDL) Examples


SQL Function
statement
CREATE Define a table, view, macro, index, trigger or
stored procedure.
DROP Remove a table, view, macro, index, trigger or
stored procedure.
ALTER Change table structure or protection definition.

Data Manipulation Language (DML)

SQL Function
statement
SELECT Select data from one or more tables.
INSERT Place a new row into a table.
UPDATE Change data values in one or more existing rows.
DELETE Remove one or more rows from a table.

Data Control Language (DCL)


SQL Function
statement
GRANT Give user privileges.
REVOKE Remove user privileges.
GIVE Transfer database ownership.

Relational Concepts

The figure below illustrates six rows of a much larger table.

Some interesting things to note about this table:

 The intersection of a row and a column is a data value. Data values come
from a particular domain. Domains represent the pool of legal values for a
column. For example, the data values in the EMPLOYEE NUMBER and
MANAGER EMPLOYEE NUMBER come from the same domain because both
columns come from the pool of employee numbers. The domain of
employee numbers might be defined as the pool of integers greater than
zero.
 The EMPLOYEE NUMBER column is marked PK, which indicates that this
column holds the Primary Key. The next 3 columns are marked FK, which
stands for Foreign Key.
 The purpose of the Primary Key is to uniquely identify each record. No
two values in a primary key column can be identical.
 A Foreign Key represents the Primary Key of another table. Relationships
between tables are formed through the use of Foreign Keys.
2.) Teradata SQL

Objectives

After completing this module, you should be able to:

 Describe the uses of the Teradata SQL SELECT statement.


 Retrieve data from a relational table using the SELECT statement.
 Use the SQL ORDER BY and DISTINCT options.
 Set a default database using the DATABASE command.
 Write SQL statements using recommended coding conventions.
 Name database objects according to Teradata SQL rules.

SELECT
Structured Query Language (SQL) consists of three types of statements,
previously defined as:

Data Definition Language (DDL)


- Used to create, drop and modify objects
Data Manipulation Language(DML)
- Used to add, delete, update and read data rows in a table
Data Control Language(DCL)
- Used to implement security and control on database objects.

Our focus in this course will be mostly on the DML portion of the language. We
will first look at the SELECT statement.

The SELECT statement allows you to retrieve data from one or more tables. In its
most common form, you specify certain rows to be returned as shown.

SELECT *
FROM employee
WHERE department_number = 401;

The asterisk, "*", indicates that we wish to see all of the columns in the table.
The FROM clause specifies from which table in our database to retrieve the rows.
The WHERE clause acts as a filter which returns only rows that meet the specified
condition, in this case, records of employees in department 401.

Note: SQL does not require a trailing semicolon to end a statement but the Basic
Teradata Query (BTEQ) utility that we use to enter SQL commands does require
it. All examples in this course will include the semicolon.

What if we had not specified a WHERE clause.

SELECT * FROM employee;

This query would return all columns and all rows from the employee table.

Instead of using the asterisk symbol to specify all columns, we could name
specific columns separated by commas:

SELECT employee_number
,hire_date
,last_name
,first_name
FROM employee
WHERE department_number = 401;
employee_number hire_date last_name first_name
-------------------- ---------- ----------- -----------
1004 76/10/15 Johnson Darlene
1003 76/07/31 Trader James
1013 77/04/01 Phillips Charles
1010 77/03/01 Rogers Frank
1022 79/03/01 Machado Albert
1001 76/06/18 Hoover William
1002 76/07/31 Brown Alan

Unsorted Results

Results come back unsorted unless you specify that you want them sorted in a
certain way. How to retrieve ordered results is covered in the next section.

ORDER BY Clause

Use the ORDER BY clause to have your results displayed in a sorted order.
Without the ORDER BY clause, resulting output rows are displayed in a random
sequence.

SELECT employee_number
,last_name
,first_name
,hire_date
FROM employee
WHERE department_number = 401
ORDER BY hire_date;

Sort Direction

In the example above, results will be returned in ascending order by hire date.
Ascending order is the default sort sequence for an ORDER BY clause. To explicitly
specify ascending or descending order, add ASC or DESC, to the end of the ORDER
BY clause. The following is an example of a sort using descending sequence.

ORDER BY hire_date DESC;

Naming the Sort Column

You may indicate the sort column by naming it directly (e.g., hire_date) or by
specifying its position within the SELECT statement. Since hire_date is the
fourth column in the SELECT statement, the following ORDER BY clause is
equivalent to saying ORDER BY hire_date.

ORDER BY 4;

Multiple ORDER BY Columns

An ORDER BY clause may specify multiple columns. No single column in an ORDER


BY clause should exceed a length of 4096 bytes, otherwise it will be truncated for
sorting purposes.

The order in which columns are listed in the ORDER BY clause is significant. The
column named first is the major sort column. The second and subsequent are
minor sort columns. In the following example, results are sorted by department
number in ascending order. Where multiple records share the same department
number, those rows are sorted by job_code in ascending order. The following
are examples:

SELECT employee_number
,department_number
,job_code
FROM employee
WHERE department_number < 302
ORDER BY department_number
,job_code;
employee_number department_number job_code
-------------------- ---------------------- ----------
801 100 111100
1025 201 211100
1021 201 222101
1019 301 311100
1006 301 312101
1008 301 312102

Note: Each column specified in the ORDER BY clause can have its own sort order,
either ascending or descending.

SELECT employee_number
,department_number
,job_code
FROM employee
WHERE department_number < 302
ORDER BY department_number ASC
,job_code DESC;
employee_number department_number job_code
-------------------- ---------------------- ----------
801 100 111100
1021 201 222101
1025 201 211100
1008 301 312102
1006 301 312101
1019 301 311100

DISTINCT

The DISTINCT operator will consolidate duplicate output rows to a single


occurrence.

Example Without DISTINCT

SELECT department_number
,job_code
FROM employee
WHERE department_number = 501;
department_number job_code
---------------------- ----------
501 512101
501 512101
501 511100

Note: Two people in department 501 have the same job code (512101). If our
purpose is simply to find out which job codes exist in department 501, we could
use DISTINCT to avoid seeing duplicate rows.

Example With DISTINCT

SELECT DISTINCT department_number


,job_code
FROM employee
WHERE department_number = 501;
department_number job_code
---------------------- ----------
501 511100
501 512101

Note: DISTINCT appears directly after SELECT, and before the first named
column. It may appear to apply only to the first column, but in fact, DISTINCT
applies to all columns named in the query. Two rows in our result example set
both have department_number 501. The combination of department_number and
job_code are distinct since the job codes differ.

Naming Database Objects

All Teradata objects, such as tables, must be assigned a name by the user when
they are created.

These rules for naming objects are summarized as follows:

Names are composed of:  a-z


 A-Z
 0-9
 _ (underscore)
 $
 #

Names are limited to 30 characters.

Names cannot begin with a number.

Teradata names are not case-sensitive.

Examples of valid names:

Accounts
Accounts_2005
accounts_over_$2000
Account#

Equivalence

Accounts and accounts represent the same table. Case is not considered.

Naming Rules

Naming Syntax

 Database names and User names must be unique within the Teradata
Database.
 Table, view, macro, trigger, index and stored procedure names must be
unique within a Database or User.
 Column names must be unique within a Table.

The syntax for fully qualifying a column name is:

Databasename.Tablename.Columnname

Example

NAME (unqualified)

EMPLOYEE.NAME (partially qualified)

PAYROLL.EMPLOYEE.NAME (fully qualified)

Note: The amount of qualification necessary is a function of your default


database setting.

Coding Conventions

SQL is considered a 'free form' language, that is, it can cover multiple lines of
code and there is no restriction on how much 'white space' (i.e., blanks, tabs,
carriage returns) may be embedded in the query. Having said that, SQL is
syntactically a very precise language. Misplaced commas, periods and
parenthesis will always generate a syntax error.

The following coding conventions are recommended because they make it easier
to read, create, and change SQL statements.

Recommended Practice

SELECT last_name
,first_name
,hire_date
,salary_amount
FROM employee
WHERE department_number = 401
ORDER BY last_name;
Not Recommended Practice

select last_name, first_name, hire_date, salary_amount


from employee where department_number = 401 order by last_name;

The first example is easy to read and troubleshoot (if necessary). The second
example appears to be a jumble of words. Both, however, are valid SQL
statements.

Default Database

Setting the Default Database

As a valid user, you will normally have access rights to your own user database
and the objects it contains. You may also have permission to access objects in
other databases.

The user name you logon with is usually your default database. (This depends on
how you were created as a user.)

For example, if you log on as:

.logon rayc;

password: xyz

then "rayc" is normally your default database.

Note the dot (.) before "logon". Commands that begin with a dot are BTEQ
commands, not SQL commands. The BTEQ command processor will read this
command; the SQL processor will not see it.

Queries you make that do not specify the database name will be made against
your default database.

Changing the Default Database

The DATABASE command is used to change your default database.

For example:

DATABASE payroll;

sets your default database to payroll. Subsequent queries (assuming the proper
privileges are held) are made against the payroll database.
Lab

Try It! For this set of lab questions you will need information from
the Database Info document.

These exercises are to be done as a pencil-and-paper


workshop. Create a small text file and write out the SQL
statements as you would enter them on-line. Click on the
buttons to the left to see the answers.

Save the file with your answers, as you will enter and run
these exercises using BTEQ scripts for the Labs in Module 3.

Answers: A. Select all columns for all departments from the


department table.
Lab A B. Using the employee table, generate a report of
Lab B employee last and first names and salary for all of
Lab C manager 1019's employees. Order the report in last
Lab D name ascending sequence.
C. Modify the previous request to show department
number instead of first name. Make it for manager
801's employees instead of manager 1019's.
D. Prepare a report of the department numbers and the
manager's employee numbers for everyone in the
employee table. Now, as a separate query, add the
DISTINCT option to the same report.

Note: Remember to save the file with your answers.

3.) Simple BTEQ

Objectives

After completing this module, you should be able to:

 Use BTEQ to submit SQL to the Teradata database.


 Set session parameters to enable
 Teradata transaction semantics.
 The SQL Flagger.

What is BTEQ?

BTEQ is a front end tool for submitting SQL queries. 'BTEQ' stands for Basic
Teradata Query program.

BTEQ is client software that resides on your network or channel-attached host.


After starting BTEQ, you will log on to Teradata using a TDP-id (Teradata
Director Program id), your user id and password. The TDP-id identifies the
instance of Teradata you are going to access.

TDP's come in two varieties - the standard TDP for channel-attached clients, and
the Micro-TDP (or MTDP) for network-attached clients.

They are involved in getting your SQL requests routed to a Parsing Engine (PE)
which validates your request and passes it to the Access Module Processors
(AMPs). AMPs retrieve the answer sets from the disks and send the response set
back to the PE which in turn forwards it to the TDP and ultimately back to you at
your session.

Where is BTEQ Located?

BTEQ is Teradata client software which is installed on mainframe hosts or


network attached clients. It operates under all host systems and local area
networks (LANs).

BTEQ Commands

Facts about BTEQ commands:

 Must be preceded by a period (.) or terminated by a semi-colon or both.


 Provide an output listing (an audit trail) of what occurred.
 Additional commands for report formatting are available.
 Are not case-sensitive.

Invoking BTEQ varies somewhat depending on the platform. In the UNIX


enviroment, simply typing in the command 'bteq' is required.

For purposes of this course, instructions for starting a lab session are contained
on each lab page.

Using BTEQ Interactively


Submitting SQL Statements with BTEQ

There are two ways to submit SQL statements to BTEQ in interactive mode:

 Type in SQL statements directly to the BTEQ prompt.


 Open another window with a text editor. Compose SQL statements using
the text editor, then cut and paste the SQL to the BTEQ prompt.

When users log on to BTEQ, they are by default assigned a single session.

Session Parameters

Session parameters include transaction semantics and the SQL Flagger.

Transaction semantics, allows you to set your session in either ANSI or


Teradata (BTET) mode. All features of Teradata SQL will work in either mode, but
each mode activates different case-sensitivity and data conversion defaults, and
so the same query might return different results in each mode.

For purposes of this course, Teradata-mode sessions will be assumed unless


otherwise specified. More on these session parameters is covered in the Teradata
SQL Application Development WBT.

Example

.SET SESSION TRANSACTION ANSI; /* Sets ANSI mode*/

.SET SESSION TRANSACTION BTET; /* Sets Teradata mode*/

Note 1: All text between /* and */ are treated as comments by BTEQ.

Note 2: The .SET SESSION commands must be entered prior to logging on to


the session.

You may also activate the ANSI Flagger, which automatically flags non-ANSI
compliant syntax with a warning but still returns the expected answer set.

Example

.SET SESSION SQLFLAG ENTRY; /* Causes non-Entry level ANSI syntax to


be flagged */

.LOGON etc.....

SELECT DATE; /* Causes a warning because keyword DATE is not ANSI


standard*/

*** SQL Warning 5821 Built-in values DATE and TIME are not ANSI.
*** Query completed. One row found. One column returned.
*** Total elapsed time was 1 seconds.

Date
--------
05/01/12

Example

.SET SESSION SQLFLAG NONE /* Disables ANSI Flagger*/

.LOGON etc.........

SELECT DATE; /* DATE keyword is not flagged */

*** Query completed. One row found. One column returned.


*** Total elapsed time was 1 second.

Date
--------
05/01/12

Note: In both cases, the date was returned.

Teradata extensions cannot be disabled, but they can be flagged for warning
using the ANSI flagger.

The SHOW CONTROL Command

The BTEQ .SHOW CONTROL command displays BTEQ settings. The following output
shows the result of this command.

.SHOW CONTROL

Default Maximum Byte Count = 4096


Default Multiple Maximum Byte Count = 2048
Current Response Byte Count = 4096
Maximum number of sessions = 20
Maximum number of the request size = 32000

EXPORT RESET
IMPORT FIELD
LOGON L7544/tdxxx
RUN
[SET] ECHOREQ = ON
[SET] ERRORLEVEL = ON
[SET] FOLDLINE = OFF ALL
[SET] FOOTING = NULL
[SET] FORMAT = OFF
[SET] FORMCHAR = OFF
[SET] FULLYEAR = OFF
[SET] HEADING = NULL
[SET] INDICDATA = OFF
[SET] NOTIFY = OFF
[SET] NULL = ?
[SET] OMIT = OFF ALL
[SET] PAGEBREAK = OFF ALL
[SET] PAGELENGTH = 55
[SET] QUIET = OFF
[SET] RECORDMODE = OFF
[SET] REPEATSTOP = OFF
[SET] RETCANCEL = OFF
[SET] RETLIMIT = No Limit
[SET] REPEATSTOP = OFF
[SET] RETCANCEL = OFF
[SET] RETLIMIT = No Limit
[SET] RETRY = ON
[SET] RTITLE = NULL
[SET] SECURITY = NONE
[SET] SEPARATOR = two blanks
[SET] SESSION CHARSET = ASCII
[SET] SESSION SQLFLAG = NONE
[SET] SESSION TRANSACTION = BTET
[SET] SESSIONS = 1
[SET] SIDETITLES = OFF for the normal report.
[SET] SKIPDOUBLE = OFF ALL
[SET] SKIPLINE = OFF ALL
[SET] SUPPRESS = OFF ALL
[SET] TDP = L7544
[SET] TIMEMSG = DEFAULT
[SET] TITLEDASHES = ON for the normal report.
[SET] UNDERLINE = OFF ALL
[SET] WIDTH = 75

BTEQ Scripts

A BTEQ script is a file that contains BTEQ commands and SQL statements. A
script is built for sequences of commands that are to be executed on more than
one occasion, i.e. monthly, weekly, daily.
How to create a BTEQ Script

To create and edit a BTEQ script, use an editor on your client workstation. For
example, on a UNIX workstation, use either the vi or text editor.

How to Submit a BTEQ Script

Start BTEQ, then enter the following BTEQ command to submit a BTEQ script:

.run file = <scriptname>

BTEQ Comments -- Teradata Extensions

The Teradata RDBMS supports comments that span multiple lines by using the
"/*" and "*/" as delimiters.

Example of a BTEQ comment:

/* You can include comments in a BTEQ


script by enclosing the comment text between “/*” and “*/”
and the comment may span multiple lines */

Script Example

Let's look at an example of a BTEQ script using ANSI standard comments. The
ANSI comment delimiter is the double dash, --.

(This script is named mod2exer.scr )

.SET SESSION TRANSACTION ANSI


.LOGON L7544/tdxxx,;

-- Obtain a list of the department numbers and names


-- from the department table.

SELECT department_number
,department_name
FROM department;

.QUIT

Note: Both Teradata style (/* */) and ANSI style (--) comments may be
included in any SQL command script.

To Execute The Script:

.run file=mod2exer.scr

(The following is the output generated by the above command.)

Script started on Sat Feb 15 10:48:19 1997


$ bteq

Teradata BTEQ 04.00.01.00 for UNIX5. Enter your logon or BTEQ command:

.run file=mod2exer.scr (this is the only user input; the rest of the commands came
from file mod2exer.scr)

.run file=mod2exer.scr
Teradata BTEQ 04.00.01.00 for UNIX5. Enter your logon or BTEQ command:

.LOGON L7544/tdxxx,

*** Logon successfully completed.


*** Transaction Semantics are ANSI.
*** Character Set Name is 'ASCII'.
*** Total elapsed time was 1 second.

BTEQ -- Enter your DBC/SQL request or BTEQ command:


-- Obtain a list of the department numbers and names
-- from the department table.

SELECT department_number
,department_name
FROM department;

*** Query completed. 9 rows found. 2 columns returned.


*** Total elapsed time was 1 second.

department_number department_name
------------------ -----------------
401 customer support
<rest of result rows are not shown in this screen capture>

BTEQ -- Enter your DBC/SQL request or BTEQ command:

.QUIT
*** You are now logged off from the DBC.
*** Exiting BTEQ...
*** RC (return code) = 0
# exit

Using BTEQ in BATCH Mode

If you prefer to write all SQL statements in a single script file, there are two
ways you may execute the script:

 Start BTEQ in interactive mode. Use the following BTEQ command to


execute the script:

.run file = mod2exer.scr

 Start BTEQ and redirect standard input to use the script file.

$bteq < mod2exer.scr

(Note: The dollar sign ‘$’ corresponds to the UNIX prompt.)

How to Capture BTEQ Session Output

From a UNIX workstation, use the script <filename> command to capture the
output of your session :

$script <filename> Logs all input and output to <filename>.

$bteq Starts BTEQ in interactive mode.

.run file = Submits pre-written script which contains BTEQ


<scriptname> commands and SQL statements.

The contents of <scriptname> and responses from the Teradata database will be
output to both the screen and the designated <filename> if one has been
designated.

How to Stop Capturing BTEQ Session Output

From a UNIX workstation, issue the following UNIX command to stop the script
command:

$exit

This closes the logging file but does not terminate the UNIX session.

Identifying Syntax Errors

BTEQ output results will display a "$" to indicate the location where the error was
detected in either the script or request. The following is an example of captured
output showing a syntax error:

Script started on Thu Oct 24 16:21:21 1996


# bteq

Teradata BTEQ 04.00.00.00 for UNIX5. Enter your logon or BTEQ command:

.logon L7544/tdxxx,

*** Logon successfully completed.


*** Transaction Semantics are ANSI.
*** Character Set Name is 'ASCII'.
*** Total elapsed time was 1 second.

BTEQ -- Enter your DBC/SQL request or BTEQ command:

SELECT department_number
,DISTINCT department_name
FROM department;

,DISTINCT department_name
$

*** Failure 3706 Syntax error, 'DISTINCT' that follows the ','
should be deleted.

Statement# 1, Info =36


*** Total elapsed time was 1 second

BTEQ -- Enter your DBC/SQL request or BTEQ command:


.quit
*** You are now logged off from the DBC.
*** Exiting BTEQ...
*** RC (return code) = 8
# exit

script done on Thu Oct 24 16:21:39 1996

The dollar sign points to the command DISTINCT. The error text tells us that
DISTINCT should be deleted. The DISTINCT command must directly follow the
SELECT command in your request.

Lab

Try It! For this set of lab questions you will need information from
the Database Info document.

To start the online labs, click on the Telnet button in the lower
left hand screen of the course. Two windows will pop-up: a
BTEQ Instruction Screen and your Telnet Window. Sometimes
the BTEQ Instructions get hidden behind the Telnet Window.
You will need these instructions to log on to Teradata.

Be sure to change your default database to the


Customer_Service database in order to run these labs.

Click on the buttons to the left to see the answers.

Answers: A. See Labs A, B, and C from Module 2 that you did on


Lab A.1 paper. You can use NotePad or another text editor to
Lab A.2 create your SQL requests again, and then simply copy
Lab A.3 and paste them into the Telnet window after you've
Lab B logged on with BTEQ.
B. Use BTEQ to submit your two reports from Lab D in
Lab C
Module 2. Observe the number of rows returned in
Lab D
your output. Which rows were eliminated due to the
DISTINCT option?

Click on the Lab B button to see the answer for this


Lab.

C. Set the ANSI Flagger ON and observe the differences it


produces.

Do this by:

Logging off of Teradata (.logoff).


Setting the flagger on (.SET SESSION SQLFLAG
ENTRY).
Relogging on to Teradata

Resubmit your query from Lab A.1.


What differences do you observe?
Why?

(Note: the ANSI Flagger is covered in more detail in


the SQL Application Development WBT)

Click on the Lab C button to see the answer for this


Lab.

D. 1) Determine the default system session transaction


mode. What command did you use?

2) Set the session transaction mode to the opposite


setting (e.g., set it to ANSI if the system default is
BTET) then verify the new setting.

Click on the Lab D button to see the answer for this


Lab.

4.) HELP Functions

Objectives

After completing this module, you should be able to:

 Obtain the definition of an existing Database, Table, View, or Macro using


the HELP and SHOW statements.
 Determine how the Teradata RDBMS will process a SQL request using the
EXPLAIN statement.
Teradata SQL Extensions

Several commands in our software are Teradata-specific. Here is a list of


Teradata extensions covered within this course.

ADD_MONTHS BEGIN/ END TRANSACTION


COLLECT/ DROP COMMENT ON
STATISTICS
CONCATENATION EXPLAIN
FALLBACK FORMAT
HELP INDEX
LOCKING MACRO Facility

• CREATE
• REPLACE
• DROP
• EXECUTE
NAMED NULLIFZERO/ZEROIFNULL
SHOW SUBSTR
TITLE TRIM
WITH WITH . . . BY

In this module, we focus on the following functions:

 EXPLAIN
 HELP
 SHOW

HELP Commands: Database objects

The HELP Command is used to display information about database objects such
as (but not limited to):

 Databases and Users


 Tables
 Views
 Macros

HELP retrieves information about these objects from the Data Dictionary. Below
are the syntactical options for various forms of the HELP command:

HELP Command

HELP
DATABASE databasename;
HELP USER username;
HELP TABLE tablename;
HELP VIEW viewname;
HELP MACRO macroname;
HELP COLUMN table or viewname.*; (all columns)
HELP COLUMN table or viewname.colname . . ., colname;

Some of the other HELP commands which will be seen later in this course
include:

HELP INDEX tablename;

HELP STATISTICS tablename;

HELP CONSTRAINT constraintname;

HELP JOIN INDEX join_indexname;

HELP TRIGGER triggername;

The HELP DATABASE Command

The HELP DATABASE command in the following example shows all objects in the
Customer_Service database. Objects may be recognized by their 'Kind'
designation as follows:

Table =T
View =V
Macro =M
Trigger =G
Join Index =J
Stored Procedure =P
HELP DATABASE Customer_Service;

Results will be displayed as follows:

Table/View/Macro Kind Comment


Name
contact T ?
customer T ?
department T ?
employee T ?
employee_phone T ?
job T ?
location T ?
location_employee T ?
location_phone T ?

All objects in this database are tables. The '?' is how BTEQ displays a null,
indicating that no user comments have been entered.

Note: To return HELP information on an object, a user must either own the
object or have at least one privilege on it.

The HELP TABLE Command

The HELP TABLE command shows the name, data type, and comment (if
applicable), of all columns in the specified table:

HELP TABLE Customer_Service.employee


ColumnName Type Comment

employee_number I System assigned


identification

manager_employee_number I ?
department_number I Department employee
works in

job_code I Job classification


designation

last_name CF Employee surname

first_name CV Employee given name


hire_date DA Date employee was hired

birthdate DA ?
salary_amount D Annual compensation
amount
Data types are as follows:

Type Description Type Description


CF CHARACTER FIXED F FLOAT
CV CHARACTER VARIABLE BF BYTE
D DECIMAL BV VARBYTE
DA DATE AT TIME
I INTEGER TS TIMESTAMP
I1 BYTEINT
I2 SMALLINT

HELP Commands: Session Characteristics

Use the HELP SESSION command to see specific information about your current
SQL session. The following output returns session information for user DBC
including the user name, log-on date and time, default database, and other
information related to his current session:

User Name DBC


Account Name DBC
Log on Date 05/02/18
Log on Time 11:54:46
Current DataBase DBC
Collation ASCII
Character Set ASCII
Transaction
Teradata
Semantics
Current DateForm IntegerDate
Session Time Zone 00:00
Default Character
LATIN
Type
Export Latin 1
Export Unicode 1
Export Unicode Adjust 0
Export KanjiSJIS 1
Export Graphic 0
Default Date Format None
To produce the formatting shown above use:

.SET FOLDLINE ON

.SET SIDETITLES ON

The SHOW Command

The SHOW command displays the current Data Definition Language (DDL) of a
database object (e.g., Table, View, Macro, Trigger, Join Index or Stored
Procedure). The SHOW command is used primarily to see how an object was
created.

Sample Show Commands

Command Returns
CREATE TABLE
SHOW TABLE tablename;
statement
CREATE VIEW
SHOW VIEW viewname;
statement
SHOW MACRO CREATE MACRO
macroname; statement

BTEQ also has a SHOW command (.SHOW CONTROL) which is different from the SQL
SHOW command. It provides information on formatting and display settings for
the current BTEQ session.

The SHOW TABLE Command

The SHOW TABLE command seen here returns the CREATE TABLE statement that
was used to create the employee table. To perform a SHOW TABLE, the user must
have a privilege on either the table itself or the containing database.

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) CHARACTER SET LATIN NOT CASESPECIFIC NOT NULL,
first_name VARCHAR(30) CHARACTER SET LATIN 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 );

Note: If a table is subsequently altered after it has been created, the SHOW
command will always reflect the most current alterations.

The SHOW VIEW Command

The SHOW VIEW command shows you the CREATE VIEW statement used to create
a view:

SHOW VIEW dept;


Result

CREATE VIEW dept


(dept_num
,dept_name
,budget
,manager)
AS
SELECT
department_number
,department_name
,budget_amount
,manager_employee_number
FROM CUSTOMER_SERVICE.department;

The view may be accessed instead of the table:

SELECT * FROM dept;

Result

dept_num dept_name budget manager


--------- ----------- -------- ---------
research &
301 46560000 1019
development
302 product planning 22600000 1016
501 marketing sales 80050000 1017
403 education 93200000 1005
402 software support 30800000 1011
401 customer support 98230000 1003
201 technical operations 29380000 1025

The SHOW Macro Command

The SHOW MACRO command shows you the statement used to create a macro:

SHOW MACRO get_depts;

Result

CREATE MACRO get_depts


AS (SELECT department_number
,department_name
,budget_amount
,manager_employee_number
FROM department;
);

The EXPLAIN Command

The EXPLAIN function looks at a SQL request and responds in English how the
optimizer plans to execute it. It does not actually execute the SQL statement
however it is a good way to see what database resources will be used in
processing your request.

For instance, if you see that your request will force a full-table scan on a very
large table or cause a Cartesian Product Join, you may decide to re-write a
request so that it executes more efficiently.

EXPLAIN provides a wealth of information, including the following:

1. Which indexes if any will be used in the query.


2. Whether individual steps within the query may execute concurrently (i.e.
parallel steps).
3. An estimate of the number of rows which will be processed.
4. An estimate of the cost of the query (in time increments).

EXPLAIN SELECT * FROM department;


*** Query completed. Ten rows found. One column returned.

Explanation

1. First, we lock a distinct CUSTOMER_SERVICE."pseudo table" for read on a


RowHash 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 is 0.15 seconds.

Lab

Try It! For this set of lab questions you will need information from the
Database Info document.

To start the online labs, click on the Telnet button in the lower
left hand screen of the course. Two windows will pop-up: a
BTEQ Instruction Screen and your Telnet Window.
Sometimes the BTEQ Instructions get hidden behind the Telnet
Window. You will need these instructions to log on to Teradata.

Click on the buttons to the left to see the answers.

Answers: A. Use the HELP DATABASE command to find all tables,


Lab A views, and macros names in the CS_Views database.
Lab B What kind of objects do you find there? Do a similar
Lab C HELP command on the Customer_Service database.
Lab D What kind of objects do you find there?
Lab E B. To see the names of the columns in the department
table, use the appropriate HELP command. (Since the
Lab F
table is in the Customer_Service database, not your
Lab G
default database, you'll have to qualify the table name
with the database name.) This is the command you may
wish to use in the future to research data names.
C. In Lab A, you may have noticed that the CS_Views
database includes a view called emp. SHOW that view.
Notice the list of short names the emp view uses in
place of full column names. To save typing, you may use
the emp view with the shortened names in place of the
employee table in any labs throughout this course. (All
lab solutions shown in this book use the employee table
in Customer_Service.)
D. Modify Lab A.1 from the previous module to cause the
answer set to appear in department name sequence. To
find out how Teradata plans to handle this request,
submit it with EXPLAIN in front of it.
E. Use the appropriate SHOW command to see the table
definition of the employee_phone table in the
Customer Service database.
F. Use the appropriate HELP command to see what kinds of
indexes exist on the customer table. To get information
about your session, use another HELP command,
however first change the display settings for
SIDETITLES and FOLDLINE to better view the session
information. Be sure to reset display attributes once you
have seen results.
G. Change your current database setting to
Customer_Service using the DATABASE command. Try
to do a SELECT of all columns and rows in the emp view.
Does it work? If not, how can you make it work?

5.) Logical and Conditional Expressions

Objectives

After completing this module, you should be able to:

 Combine the following types of operators into logical expressions:


 comparison operators
 [NOT] IN
 IS [NOT] NULL
 LIKE
 Form expressions involving NULL values.
 Qualify a range of values.
 Search for a partial string within a string expression.
 Combine multiple logical expressions into a conditional expression using
AND and OR.
Logical Operators

Operators are symbols or words that cause an 'operation' to occur on one or


more elements called 'operands'.

Logical expressions combine operands and operators to produce a Boolean


(true/false) result. Logical expressions can be combined into conditional
expressions which are used in the WHERE clause of a SELECT statement.

Types of Operators in Logical Expressions

Operator Syntax Meaning


= equal
<> not equal
> greater than
< less than
>= greater than or equal to
<= less than or equal to
BETWEEN <a> AND <b> inclusive range
[NOT] IN <expression> is in a list
or
<expression> is not in a list
IS [NOT] NULL <expression> is null
or
<expression> is not null
[NOT] EXISTS* table contains at least 1 row
or
table contains no rows
LIKE partial string operator

The EXISTS operator is covered in the Teradata Advanced SQL course.

BETWEEN -- Numeric Range Testing

To locate rows for which a numeric column is within a range of values, use the
BETWEEN <a> AND <b> operator. Specify the upper and lower range of values
that qualify the row.

The BETWEEN operator looks for values between the given lower limit <a> and
given upper limit <b> as well as any values that equal either <a> or <b>
(i.e., BETWEEN is inclusive.)

Example

Select the name and the employee's manager number for all employees
whose job codes are in the 430000 range.

SELECT first_name
,last_name
,manager_employee_number
FROM employee
WHERE job_code BETWEEN 430000 AND 439999;
first_name last_name manager_employee_number
----------- ----------- ------------------------------
Loretta Ryan 801
Armando Villegas 1005

An alternative syntax is shown below:

SELECT first_name
,last_name
,manager_employee_number
FROM employee
WHERE job_code >= 430000
AND job_code <= 439999;
Note that using BETWEEN requires only one mention of the column name being
tested, whereas without BETWEEN the column name must be provided for each
condition tested.

BETWEEN -- Character Range Testing

Use the BETWEEN <a> AND <b> operator to locate rows for which a character
column is within a range of values. Specify the upper and lower range of values
that qualify the row. BETWEEN will select those values which are greater than or
equal to <a> and less or equal to <b>. (BETWEEN is inclusive.)

SELECT last_name
FROM employee
WHERE last_name BETWEEN 'r' AND 's';

last_name
------------
Ryan

Note: 'Stein' is not included because 'S_____' sorts lower than 'Stein'. (Teradata
is not case-sensitive by default.)

Set Operator IN

Use the IN operator as shorthand when multiple values are to be tested. Select the
name and department for all employees in either department 401 or 403. This
query may also be written using the OR operator which we shall see shortly.

SELECT first_name
,last_name
,department_number
FROM employee
WHERE department_number IN (401, 403);

first_name last_name department_number


----------- ----------- ---------------------
Darlene Johnson 401
Loretta Ryan 403
Armando Villegas 403
James Trader 401
Set Operator NOT IN

Use the NOT IN operator to locate rows for which a column does not match any of
a set of values. Specify the set of values which disqualifies the row.

SELECT first_name
,last_name
,department_number
FROM employee
WHERE department_number NOT IN (401, 403) ;

first_name last_name department_number


----------- ----------- ---------------------
Carol Kanieski 301
John Stein 301

NOT IN vs. OR

NOT IN provides a shorthand version of a 'negative OR' request. The following is


an example using the OR operator for the query example given above.

Select the name and the department for all employees who are NOT members of
departments 401 and 403.

SELECT first_name
,last_name
,department_number
FROM employee
WHERE NOT (department_number=401
OR
department_number=403);

first_name last_name department_number


----------- ----------- ---------------------
Carol Kanieski 301
John Stein 301

NULL

The following are facts about nulls:

 NULL is used to represent the absence of a data value.


 NULL is not the same as having a value of zero or spaces.
 NULL indicates that a data value is missing or unknown.
 NULL in a comparison operation produces an unknown result.
 When doing an ascending sort on a column with NULL, NULLs sort before
negative values (numeric) and before blank values (character).
 To prohibit NULLs, a column must be defined as NOT NULL.
 Null columns may be compressed to occupy zero row space.

Arithmetic and Comparison Operation on NULL

The following logic applies to operations on NULLs:

Col A Operation Col B Results


10 + NULL NULL
10 - NULL NULL
10 * NULL NULL
10 / NULL NULL
10 > NULL UNKNOWN
10 < NULL UNKNOWN
10 >= NULL UNKNOWN
10 <= NULL UNKNOWN
10 = NULL UNKNOWN
10 <> NULL UNKNOWN
NULL > NULL UNKNOWN
NULL < NULL UNKNOWN
NULL >= NULL UNKNOWN
NULL <= NULL UNKNOWN
NULL = NULL UNKNOWN
NULL <> NULL UNKNOWN

Using NULL in a Select

Use NULL in a SELECT statement, to define that a range of values either IS NULL
or IS NOT NULL.

The following table lists two employees with unknown telephone extensions:

To list employee numbers in this table with unknown extensions:

SELECT employee_number
FROM employee_phone
WHERE extension IS NULL;
employee_number
--------------------
1025
1005

To list employee numbers of people with known extensions:

SELECT employee_number
FROM employee_phone
WHERE extension IS NOT NULL;
employee_number
--------------------
1008
1013

LIKE Operator

The LIKE operator searches for patterns matching character data strings.

You must provide two parameters for the LIKE operator: a string expression to
be searched and a string pattern for which to search.

The string can contain specific characters, as well as the following "wildcards":

% (indicates zero or more character positions)


_ (indicates a single character position)

Here are some examples using the LIKE operator:

String pattern
Meaning:
example:
LIKE 'JO%' begins with 'JO'
LIKE '%JO%' contains 'JO' anywhere
LIKE '__HN' contains 'HN' in 3rd and 4th position
LIKE '%H_' contains 'H' in next to last position

LIKE Operator -- Case-Blind Comparison

Case-Sensitivity: ANSI vs. BTET session transaction mode

Case-sensitivity of string comparisons is handled differently in the two different


session transaction modes (ANSI or BTET). This can lead to different results for a
comparison when run from sessions with different transaction modes. To ensure
consistent behavior, either case-sensitive or case-blind compares, use the
following:
UPPER or LOWER operators for case-blind comparisons
CASESPECIFIC operator for case-sensitive comparisons

Case-Blind Compare

The UPPER function converts a string to uppercase. Use the UPPER string
function on both strings being compared to ensure a case-blind comparison
regardless of the session transaction mode. The LOWER function may be
similarly used.

The NOT CASESPECIFIC data attribute can also be used to force case-blind
compares, however it is not an ANSI-compliant operator.

Problem

Display the full name of employees whose last name contains the letter "r"
followed by the letter "a".

Teradata Mode Solution

SELECT first_name
,last_name
FROM employee
WHERE last_name LIKE '%ra%';

first_name last_name
------------------------------ --------------------
James Trader
Peter Rabbit
I.B. Trainer
Robert Crane
Larry Ratzlaff

Since we are in Teradata (BTET) mode, the default for comparisons is non-case-
specific. Thus, we could have also used LIKE '%Ra%' or LIKE '%RA%' and
produced the same result.

ANSI Mode Solution

SELECT first_name
,last_name
FROM employee
WHERE last_name LIKE '%ra%';

first_name last_name
------------------------------ --------------------
James Trader
I.B. Trainer
Robert Crane

Since we are in ANSI mode, the default for comparisons is case-specific. Thus,
we will not pick up Ratzlaff or Rabbit, unless we use 'case blind' testing, seen in
the next example.

SELECT first_name
,last_name
FROM employee
WHERE LOWER(last_name) LIKE LOWER('%ra%');

first_name last_name
------------------------------ --------------------
James Trader
Peter Rabbit
I.B. Trainer
Robert Crane
Larry Ratzlaff
By applying the LOWER function to each side of the comparison, all testing is
done in a 'case blind' mode. UPPER could have also been used. We could also
have used LIKE '%ra%' (NOT CASESPECIFIC) to produce this result,
however this is not an ANSI standard approach.

LIKE Operator - Case-Sensitive Comparison

Use the CASESPECIFIC data attribute on one or both of the string expressions
being compared to ensure a case-sensitive comparison, regardless of the session
transaction mode. CASESPECIFIC is a Teradata extension.

Problem

Display the full name of employees whose last name contains "Ra". This is a
case-sensitive test.

Teradata Mode Solution

SELECT first_name
,last_name
FROM employee
WHERE last_name (CASESPECIFIC) LIKE '%Ra%';

first_name last_name
------------------------------ --------------------
Peter Rabbit
Larry Ratzlaff

The default comparison for Teradata mode is not case-specific.

Use of the Teradata extension (CASESPECIFIC) forces a case-specific comparison.

Because we used the case-specific designator, we don't get James Trader in our
answer set but only get answers that contain an uppercase "R". The name
'LaRaye' would have also appeared in this answer set, if it existed in the table.
Using LIKE 'Ra%' will return only names that begin with "Ra".

ANSI Mode Solution

SELECT first_name
,last_name
FROM employee
WHERE last_name LIKE '%Ra%';

first_name last_name
------------------------------ --------------------
Peter Rabbit
Larry Ratzlaff

The default comparison for ANSI mode is case-specific.

Use of the Teradata extension (CASESPECIFIC) is not required. This could have
also been submitted with LIKE 'Ra%' and produced the same result, however it
would have missed a name like 'LaRaye'.

LIKE Operator -- Using Quantifiers

To extend the pattern matching functions of the LIKE operator, use quantifiers.

There are three such quantifiers:

ANY — any single condition must be met (OR logic)


SOME — same as ANY
ALL — all conditions must be met (AND logic)

ANY and SOME are synonyms. Using LIKE ANY and LIKE SOME will give the same
result.
Problem

Display the full name of all employees with both "E" and "S" in their last name.

Solution

SELECT first_name
,last_name
FROM employee
WHERE last_name LIKE ALL ('%E%', '%S%');

first_name last_name
---------- ----------
John Stein
Carol Kanieski
Arnando Villegas

Problem

Display the full name of all employees with either an "E" or "S" in their last
name.

Solution

SELECT first_name
,last_name
FROM employee
WHERE last_name LIKE ANY ('%E%', '%S%');

first_name last_name
----------- -----------
John Stein
Carol Kanieski
Arnando Villegas
Darlene Johnson
James Trader

LIKE with ESCAPE Character

The "_" and "%" symbols are used as 'wildcards' in the string expression of the
LIKE construct. However, what if one of the wildcard symbols is in the expression
you are evaluating. For example, to search for the substring "95%", you must
define an ESCAPE character to instruct the Parser to treat the '%' as a non-
wildcard character.

To Summarize:

 The ESCAPE feature of LIKE lets wildcard characters be treated as non-


wildcards.
 Characters following the escape character are not treated as wildcards.

Problem

List all objects defined in the Teradata Database Data Dictionary whose names
contain "_" (underscore) as the second character.

Solution

SELECT tablename
FROM dbc.tables
WHERE tablename LIKE '_Z_%' ESCAPE 'Z';

TableName
------------------------------
M_7_B
t_wt_erd1

Things To Notice

 The defined escape character is the letter 'Z'.


 The first "_" (underscore) seen represents a wildcard - i.e., any single
arbitrary character.
 The "Z_" sequence tells the Parser that the second "_" (underscore) is
treated as a character, not as a wildcard.
When you define an ESCAPE character, any use of the ESCAPE character in the
string expression must be immediately followed by either the "_", "%", or the
ESCAPE character itself.

Assume the escape character is defined to be the letter 'G'.

LIKE 'G_' means the underscore is treated as an underscore, not as a wildcard.


LIKE 'G%' means the percent sign is treated as a percent sign, not as a
wildcard.
LIKE 'GG' means the two consecutive 'G' characters should be treated as a
single 'G', not as an escape character.

Example

LIKE '%A%%AAA_' ESCAPE 'A'

Searches for the following pattern:


- any number of arbitrary characters, followed by
- the "%" single character, followed by
- any number of arbitrary characters, followed by
- the "A" single character, followed by
- the "_" single character, which is the last character in the string.

Logical Operator -- AND

Logical operators AND, OR and NOT allow you to specify complex conditional
expressions by combining one or more logical expressions.

Logical Operator AND

The logical operator AND combines two expressions, both of which must be true
in a given record for them to be included in the result set.

Boolean Logic Table


True AND True = True
False AND True = False
True AND False = False
False AND False = False

True OR True = True


True OR False = True
False OR True = True
False OR False = False

NOT True = False


NOT false = True

Problem

Display the name and employee number of employees in department 403 who
earn less than $35,000 per year.

Solution

SELECT first_name
,last_name
,employee_number
FROM employee
WHERE salary_amount < 35000.00
AND department_number = 403 ;

first_name last_name employee_number


----------- ----------- --------------------

Loretta Ryan 1005

Logical Operator -- OR

The logical operator OR combines two expressions. At least one must be true in a
given record for it to be included in the result set.

Problem

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

Solution

SELECT first_name
,last_name
,employee_number
FROM employee
WHERE salary_amount < 35000.00
OR department_number = 403;

Result

first_name last_name employee_number


---------- ---------- ----------------
Arnando Villegas 1007
Carol Kanieski 1008
Loretta Ryan 1005
John Stein 1006

Multiple AND . . . OR

You want to find all employees in either department 401 or department 403
whose salaries are either under $35,000 or over $85,000.

SELECT last_name
,salary_amount
,department_number
FROM employee
WHERE (salary_amount < 35000
OR salary_amount > 85000)
AND (department_number = 401
OR department_number = 403) ;

Logical Operators -- Combinations


Operator Procedures

Parentheses can be used to force an evaluation order. In the presence of


parentheses, expressions are evaluated from the inner-most to outer-most set of
parenthetical expressions.

In the absence of parentheses, SQL uses the default precedence of the Boolean
operators. By default, NOT has higher precedence than AND which has higher
precedence than OR. Operators that have the same precedence level are
evaluated from left to right (e.g., multiple ORs or multiple ANDs).

If we remove the parentheses from the example above, our conditional


expression gets evaluated in a totally different order. If we were to use it in a
query, it would yield different results.

NOT has the highest precedence of the three operators.


Logical Operators -- Using Parentheses

Problem

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

Solution

SELECT last_name
,department_number
,job_code
FROM employee
WHERE (department_number = 401
OR department_number = 403)
AND (job_code = 412101
OR job_code = 432101) ;

Result

last_name department_number job_code


----------- --------------------- ----------
Villegas 403 432101
Johnson 401 412101

If we accidentally left the parentheses out of our statement, would we get the
same results?

SELECT last_name
,department_number
,job_code
FROM employee
WHERE department_number = 401
OR department_number = 403
AND job_code = 412101
OR job_code = 432101;
last_name department_number job_code
---------- --------------------- ---------
Villegas 403 432101
Johnson 401 412101
Trader 401 411100

Question
James Trader does not have either job code. Why was he selected?

Answer
Without parentheses, the default precedence causes the expression to be
evaluated as follows:

SELECT last_name
,department_number
,job_code
FROM employee
WHERE department_number = 401
OR (department-number = 403
AND job_code = 412101)
OR job_code = 432101;

Remember, if any of the expressions that OR combines are true, the result is
true. Since James Trader is in department_number 401, that expression
evaluates to true. Therefore the row qualifies for output.

Multiple AND

Use multiple ANDs if you need to locate rows which meet all of two or more sets
of specific criteria.

For example, what happens if we take the previous example, and replace all the
ORs with ANDs?

SELECT last_name
,department_number
,job_code
FROM employee
WHERE department_number = 401
AND department_number = 403
AND job_code = 412101
AND job_code = 432101;
No rows will be found. Why?

Answer

For a row to be displayed in this answer set, an employee would have to be in


department numbers 401 and 403. While we could conceive of an employee who
works in two departments, the employee table has only one field for department
number. There is no way that any row in this table can contain more than one
department number. This query never will return any rows. A more realistic
example follows.

Problem

Find all employees in department number 403 with job_code 432101 and a
salary greater than $25,000.

Solution

SELECT last_name
,department_number
,job_code
,salary_amount
FROM employee
WHERE department_number = 403
AND job_code = 432101
AND salary_amount > 25000.00 ;

Result

last_name department_number job_code salary_amount


----------- ---------------------- ---------- ----------------
Lombardo 403 432101 31000.00
Villegas 403 432101 49700.00
Charles 403 432101 39500.00
Hopkins 403 432101 37900.00
Brown 403 432101 43700.00

Logical NOT

Place the NOT operator in front of a conditional expression or in front of a


comparison operator if you need to locate rows which do not meet specific
criteria.

Problem

Select the name and employee number of employees NOT in department 301.

Solution for NOT Operator

SELECT first_name
,last_name
,employee_number
FROM employee
WHERE department_number NOT = 301;

Solution for NOT Condition

SELECT first_name
,last_name
,employee_number
FROM employee
WHERE NOT (department_number = 301);

Result (Note that both approaches return the same result.)

first_name last_name employee_number


------------ ------------ --------------------
Arnando Villegas 1007
James Trader 1003
Loretta Ryan 1005
Darlene Johnson 1004

Lab

Try It! For this set of lab questions you will need information from the
Database Info document.

To start the online labs, click on the Telnet button in the lower
left hand screen of the course. Two windows will pop-up: a
BTEQ Instruction Screen and your Telnet Window.

Sometimes the BTEQ Instructions get hidden behind the Telnet


Window. You will need these instructions to log on to Teradata.
Be sure to change your default database to the
Customer_Service database in order to run these labs.

Click on the buttons to the left to see the answers.

Answers: A. Management needs a list with employee number, last


Lab A name, salary and job code of all employees earning
Lab B between $40,001 and $50,000. Produce this report using
Lab C the comparison operators and sort by last name.
Lab D
Modify the query to use the BETWEEN operator and sort
Lab E
by salary descending.
Lab F
Lab G
B. Management requests a report of all employees in
departments 501, 301, and 201 who earn more than
$30,000. Show employee number, department number,
and salary. Sort by department number and salary
amount within department.
C. Display location number, area code, phone number,
extension, and description from the location_phone
table if the description contains the string ‘manager'.
Sort by location number.
D. List customers from the customer table identified by:
1. An unknown parent customer number; and
2. A known sales employee number.

Display all columns except parent customer number.


Order results by customer number.

E. Create a report that lists all location numbers in area


code 415 not dedicated to any manager. Include all
columns except comment and extension. Sequence by
phone number.
F. List all job codes in the 400000 series that are
management and all Analyst positions regardless of job
code value. List job code and description for the selected
rows. Sort by description. Submit again using EXPLAIN to
look at how the Teradata RDBMS handled this request.
G. List the location numbers in area codes 415 or 617 which
have no phone extensions. Order by area code and
phone number. Include all columns of the table except
for description and comment line columns. Notice how
NULLs appear in your output.
6.) Data Types and Conversions

Objectives

After completing this module, you should be able to:

 Define the data type for a column in a table.


 Compute values using arithmetic functions and operators.
 Convert data from one type to another.
 Manipulate the DATE data type.

Data Types

Every column in a row is associated with a data type that defines the kind of
values it accepts. These data types are associated with the fields when the table
is created. Data types fall into one of the four categories shown below:

Data Type Holds


Character Data Character Strings

Byte Data Binary Data Strings

Numeric Data Numbers

Date/Time Data Dates,Times,Timestamps,Time


Intervals, Periods

Note:
Time, Timestamps, Intervals are
covered in the Teradata SQL Advanced
course.

Periods are covered in the Teradata SQL


Application Development course.
Geospatial Data Geographic locations of physical
boundaries

Note:
Geospatial data types are covered in
the SQL Application Development course.

Character Data
There are two data types for holding character data:

 CHAR - has fixed-length character strings.


 VARCHAR - has variable-length character strings.

In both cases, the maximum string length is 64,000 characters. String size is
specified in parentheses after the keyword CHAR or VARCHAR as in CHAR(20) or
VARCHAR(20). There are subtle differences between the two.

In the case of CHAR, if you insert a character string less than the specified size
(20 in the above example), the system will append and store trailing blanks as
needed to expand the string to the specified length. The size specified on a
VARCHAR field represents a maximum length. The system will not pad the
contents with trailing blanks. (It will use two extra bytes to store the length
internally however.)

When you know that data will always be a specific length (e.g., a Mail Stop that
is a four-character length) use CHAR. You save the two bytes that VARCHAR would
use to store the length. When data does not have a fixed length (e.g., last
names), VARCHAR makes more efficient use of the space, because it does not pad
values with trailing blanks.

Character Data Description Example


CHAR (size) Fixed length string last_name CHAR(20)
Max: 64,000 characters
Sample contents:
'Ryan__________'
VARCHAR (size) Variable length string first_name VARCHAR(30)
CHAR VARYING (size) Max: 64,000 characters
CHARACTER VARYING Sample contents:
(size) 'Loretta'
LONG VARCHAR Equivalent to
VARCHAR (64000)

Note: VARCHAR(size), CHAR VARYING(size), and CHARACTER VARYING(size) are all


equivalent synonyms.

LONG VARCHAR is equivalent to a maximum VARCHAR.

Character strings may be defined using any one of the following character sets:

Character Set Max Length


Latin 64,000 (English language default)
Kanji1 64,000

KanjiSJIS 64,000
Unicode 32,000 (two bytes per character)

Graphic 32,000 (two bytes per character)

Examples

first_name VARCHAR(30) CHARACTER SET LATIN

image_abc CHAR(32000) CHARACTER SET GRAPHIC

Byte Data

Teradata supports two data types for holding binary data:

 BYTE.
 VARBYTE.

BYTE is for fixed length binary strings. VARBYTE is for variable length binary
strings. These data types are used for storing binary objects such as digital
images, executable objects, flat files, etc.

Byte Data Description

BYTE (size) Fixed length


Binary string
Default: (1)
Max: 64,000 bytes

VARBYTE (size) Variable length


Binary string
Default: (1)
Max: 64,000 bytes

Note: BYTE columns are not covertible to other data types.

Numeric Data

The following numeric data types are available:


Data Type Description Examples
BYTEINT* Whole number basket_count BYTEINT
Range -128 to 127 +125
Storage: 1 byte
SMALLINT Whole number area_code SMALLINT
Range: -32,768 to +00213 (up to 5 digits)
32,767
Storage: 2 bytes
INTEGER Whole number phone INTEGER
Range: -2,147,483,648 +0006495252 (up to 10 digits)
to 2,147,483,647
Storage: 4 bytes
BIGINT Whole number international_phone BIGINT
Range ± +0000010807934842145 (up to 19
9,233,372,036,854,775, digits)
807
Storage: 8 bytes
DEC(m, n) 'm' is total number of salary_amount DEC (10,2)
DECIMAL(m, digits. (m <= 18) +00035000.00
n) 'n' is precision places to
NUMERIC(m, the right of decimal
n) point.
(Small Max Size =18 digits
Decimal) Storage: 2 to 8 bytes
DEC(m, n) 'm' is total number of sheet_thickness DEC (32,30)
DECIMAL(m, digits. (18 < m <= 38) +01.12349878279278758297727849
n) 'n' is precision places to 7827
NUMERIC(m, the right of decimal
n) point.
(Large Max Size = 38 digits
Decimal) Storage: 16 bytes
FLOAT Floating Point Format salary_factor FLOAT
(IEEE) +4.35400000000000E-001
2x10-307 to 2x10+308
Storage: 8 bytes

FLOAT Internally represented


[(precision)] as FLOAT
REAL Internally represented
as FLOAT
DOUBLE Internally represented
PRECISION as FLOAT
* Non-ANSI standard data type

Date Data

DATE represents a calendar date. It simplifies handling and formatting dates


common to business applications. DATE is stored as an integer, using the
following formula:

(year - 1900) * 10000 + (month * 100) + day

The following chart shows how the DATE data type is stored internally as an
integer by Teradata.

Data Type Description Examples

DATE hire_date DATE


Specially formatted integer:
+0000990921 (2-
YYMMDD through 1999
digit year)
YYYMMDD from 2000
+0001000215 (3-
onward
digit year)

In the first example, the date being represented is September 21, 1999.
In the second example, the date being represented is February 15, 2000.

Note that the year is represented as an offset from the year 1900 in both cases.
Note, this is how the date is stored internally. How you see the date in a report
depends on how the date is formatted.

The recommended display format for DATE values is ‘YYYY-MM-DD’. This format
will avoid problems that may occur from formats specifying only two digits for
the year.

Example

2009-03-14 formatted as ‘YY-MM-DD’ displays as 09-03-14, also the


representation for 1909-03-14.
2009-03-14 formatted as ‘YYYY-MM-DD’ displays as 2009-03-14, which is
unambiguous.

Note: Formatting techniques for dates are discussed in the forthcoming module
'Output Attributes'.

Arithmetic Operators
Teradata provides six binary arithmetic operators and two unary arithmetic
operators. They are defined in the tables below:

Binary Operators (require two operands)

Operator Definition
** exponentiation
* Multiply
/ Divide
MOD Modulos (remainders)
+ Add
- Subtract

Unary Operators (require a single operand)

Operator Definition
+ Positive value
- Negative value

Teradata supports two arithmetic operators which provide additional functionality


beyond ANSI SQL:

** (exponentiation)
MOD (modulo arithmetic)

** (exponentiation) is used in the form: <n>**<arg>, where <n> is


raised to the power of <arg>.

Example

4**3 = 4 * 4 * 4 = 64

MOD is the modulo operator. It calculates the remainder in a division operation.

Example

60 MOD 7 = 4
Sixty divided by 7 equals 8, with a remainder of 4

Arithmetic Functions
Teradata supports several arithmetic functions which provide additional
capabilities beyond those available in ANSI SQL. They are described in the table
below:

Function Result
ABS (arg) Absolute value
EXP (arg) Raises e to the power of arg (e ** arg)
LOG (arg) Base 10 logarithm
LN (arg) Base e (natural) logarithm
SQRT (arg) Square root

Arg is any constant or variable numeric argument.

Examples

SQRT (16) = 4

ABS (a) is equivalent to a positive a, regardless of whether the actual a is


positive or negative.

If a = -600 then ABS (a) = 600


If a = +400 then ABS (a) = 400

Computed Values

Use arithmetic expressions in your SELECT to perform calculations on data in the


table. Arithmetic expressions will allow you to do two things:

 Re-label the column heading for purposes of displaying the output.


 Perform the calculation on the data values in that column.

Example

Create an alphabetical list with monthly salary of department 401 employees.

SELECT last_name
,first_name
,salary_amount/12
FROM employee
WHERE department_number = 401
ORDER BY last_name ;
salary_amount/
last_name first_name
12
---------- ----------
--------------------
Johnson Darlene 3025.00
Trader James 3154.17

Note: salary_amount/12 is considered a 'computed column', because an


arithmetic operation is performed on the underlying value. Also, the column title
reflects the computation performed.

Teradata Built-in Functions

The following functions are Teradata extensions to SQL.

Literal, Constant, and Calculator Features

Character Literals

You may add character literals to your SELECT statement:

SELECT 'Employee'
,last_name
,first_name
FROM employee ;
Employee last_name first_name
-------- --------- ----------
Employee Stein John
Employee Kanieski Carol
Employee Ryan Loretta

Numeric Constants:

You may also add numeric constants to your SELECT statement:

SELECT 12345
,last_name
,first_name
FROM employee ;
12345 last_name first_name
----- --------- ----------
12345 Stein John
12345 Kanieski Carol
12345 Ryan Loretta

Calculator Mode:

You may use numeric expressions to do calculations:

Calculation Result Comment


SELECT 2*250; 500 Simple multiplication
SELECT 1.01 + 2.2; 3.2 Uses greatest possible precision

SELECT 10/3.000; 3.333 Rounds off

SELECT 10/6.000; 1.667 Rounds up

MOD Operator

The MODULO or remainder operator is a Teradata extension which calculates the


remainder in a division operation. In earlier versions of Teradata SQL, MODULO
was used significantly for DATE arithmetic. With the addition of the EXTRACT
function (seen in a later module), MODULO is less commonly used for date
extraction operations (i.e., extracting the month from a date).

Example

7 ÷ 4 = 1 remainder of 3
Therefore 7 MOD 4 = 3
Problem

Identify zip codes in the location table ending in four zeros.

SELECT customer_number
,zip_code
FROM location
WHERE zip_code MOD 10000 = 0;

customer_number zip_code
------------------- -----------
10 940710000
14 1210000

You could do this search with string comparisons, but it is more efficient to use
MOD because no character conversion is required.

Note: Leading zeros are suppressed by default.

DATE Data Type

The Teradata DATE data type is used to store calendar dates representing year,
month and day. It is stored internally as a four-byte integer.

The Teradata database performs basic DATE handling functions including:

 Month-to-month conversions.
 Year-to-year conversions.
 Leap-year conversions.
 Dates prior to 1900.
 Dates after 2000.

The database treats the DATE data type as an INTEGER value but does not permit
invalid calendar dates. The system encodes dates using the formula:

((YEAR - 1900) * 10000) + MONTH * 100) + DAY

For March 31, 1997 the calculation is:

YEAR = (1997 - 1900) * 10000 = 970000


MONTH = (3 * 100) = 300
DAY = = 31
DATE = = 970331

For March 31, 2004 the calculation is:

YEAR = (2004 - 1900) * 10000 = 1040000


MONTH = (3 * 100) = 300
DAY = = 31
DATE = = 1040331

For January 1, 1900 the result is 000101.

For dates before Jan 1, 1900, the integer calculation returns a negative number.
Remember, this is only how the date is stored, not how it is represented in a
query output.

DATE Arithmetic

SQL permits us to perform arithmetic calculations on DATE. When the DATE


keyword is SELECTed it is a system variable which represents the current date.
(CURRENT_DATE may also be used and is the preferred ANSI standard). As we
saw in the previous example, the DATE keyword is always replaced with the
current system date.

Find Syntax
The date 30 days from today SELECT DATE + 30;

Since days is the basic unit, we need to express a year in terms of the number of
days it contains. DATE + 365 (or in a leap-year, DATE + 366), gives us the date
one year from today.

Find Syntax
The date 1 year from now SELECT DATE + 365;

How would you find a person's age (in rounded years)?

SELECT (DATE-birthdate)/365
FROM employee
WHERE last_name = 'Stein';

((Date-birthdate)/365)
----------------------
45

This example takes today's date, (encoded as an integer) and "subtracts" John
Stein's birth date, (also encoded as an integer) and divides by the number of
days in a year (365).

Suppose today's date is 980826 and John's birth date is 531015. If you did this
as a straight integer subtraction, you would find that 980826 - 531015 = 449811
- not a legal date. Because these are DATE data types, not INTEGERS, the
subtraction operator actually returns the number of days between the two
operands instead of subtracting the INTEGERs.

(DATE - birthdate) thus provides us with the number of days elapsed between a
birth date and today. Dividing that amount by the number of days in a year
(365) gives us John's age in years. To account for the leap year, we should
divide by 365.25 to get a more precise number of years.

Problem

Find employees with more than 30 years of service.

SELECT last_name
,hire_date
FROM employee
WHERE (DATE-hire_date)/365 > 30;
last_name hire_date
-------------------- ---------
Trainer 73/03/01
Crane 78/01/15
Rogers 77/03/01
Brown 76/07/31
Stein 76/10/15
Phillips 77/04/01
Hopkins 77/03/15
Lombardo 77/02/01
Kanieski 77/02/01
Trader 76/07/31
Wilson 78/03/01
Johnson 76/10/15
Rogers 78/03/01
Hoover 76/06/18
Villegas 77/01/02
Runyon 78/05/01
Ryan 76/10/15
Daly 77/03/15

The example shows that operations using DATE may be included in the WHERE
clause.

Date Function ADD_MONTHS

The ADD_MONTHS function allows the addition of a specified number of months to


an existing date, resulting in a new date.

The format of the function is:

ADD_MONTHS (date, n)

where n is a number or an expression representing the number of months to be


added to the date.

The following examples demonstrate its usage.

Query Results
SELECT DATE; /* March 20, 2001 */ 01/03/20
SELECT ADD_MONTHS (DATE, 2) 2001-05-20
SELECT ADD_MONTHS (DATE, 12*14) 2015-03-20
SELECT ADD_MONTHS (DATE, -3) 2000-12-20

Note: The results of the ADD_MONTH function are always displayed in YYYY-MM-DD
format.

ADD_MONTHS may also be applied to a literal date, which must be specified in the
YYYY-MM-DD format.

Query Results
SELECT ADD_MONTHS ('2004-07-31', 2) 2004-09-30
SELECT ADD_MONTHS ('2003-12-31', 2) 2004-02-29
SELECT ADD_MONTHS ('2003-12-31', 14) 2005-02-28

ADD_MONTHS accounts for the Gregorian calendar and knows how many days are
in each month, including leap years such as 2004.

Comparison of ADD_MONTHS and simple DATE arithmetic

Because of the variable number of days in a month, ADD_MONTH provides a much


higher degree of accuracy when projecting dates based on month increments.
Problem

Show the date two month from today (March 20, 2001) using both ADD_MONTHS
and simple arithmetic methods.

SELECT DATE
,ADD_MONTHS(DATE, 2)
,DATE + 60;

Date ADD_MONTHS (Date, 2) Date+60)


--------- -------------------- ----------
01/03/20 2001-05-20 01/05/19

Time Related Data

Teradata supports two data types for holding time-related data:

 TIME (WITH ZONE)


 TIMESTAMP (WITH ZONE)

Time is represented as a TIME data type which in reality carries three different
fields of information: hours, minutes and seconds. It also has 'clock intelligence'
in its implementation, just as DATE has calendar intelligence, thus making
possible complex calculations.

TIMESTAMP is a data type which combines both DATE and TIME into a single data
type.

Both TIME and TIMESTAMP have a WITH ZONE option, which allows for time-zone
dependent storage and processing of time related information.

Time Data Description


TIME Single column - representing 3 fields
6 Bytes Length:
- Hour - Byteint
- Min - Byteint
- Secs. - Dec(8,6)
TIME WITH ZONE Single column - representing 5 fields
6 Bytes TIME:
- Hour - Byteint
- Min - Byteint
- Secs. - Dec(8,6)
2 Bytes ZONE:
- Hour - Byteint
- Minute - Byteint

Timestamp Data Description


TIMESTAMP Single column - representing 6 fields
10 Bytes Length:
Date = 4 Bytes
Time = 6 Bytes
Single column - representing 8 fields
12 Bytes Length:
TIMESTAMP WITH
- Date = 4 Bytes
ZONE
- Time = 6 Bytes
- Zone = 2 Bytes

Note: TIME and TIMESTAMP data types are covered in greater detail the
Advanced Teradata SQL Web-based training.

Interval Data Types

Interval data types represent a displacement between two points in time.


Intervals are stored internally as one or multiple numeric fields combined into a
single data type.

There are two general categories of INTERVAL data types:

1. Year-Month Intervals
2. Day-Time Intervals

Year-Month Intervals

The following Year-Month interval data types are available:

 YEAR
 YEAR TO MONTH
 MONTH

Day-Time Intervals

The following Day-Time interval data types are also available:

 DAY
 DAY TO HOUR
 DAY TO MINUTE
 DAY TO SECOND
 HOUR
 HOUR TO MINUTE
 HOUR TO SECOND
 MINUTE
 MINUTE TO SECOND
 SECOND

Note: INTERVAL data types are covered in greater detail the Advanced Teradata
SQL Web-based training.

Data Conversions Using CAST

The CAST function allows you to convert a value or expression from one data
type to another. For example:

Numeric to Numeric Conversion

SELECT CAST (50500.75 AS INTEGER);


Result: 50500 (truncated),

SELECT CAST (50500.75 AS DEC (6,0));


Result: 50501. (rounded).

When you cast from a decimal to an integer, the system discards everything to
the right of the decimal point. In our example, even though the decimal portion
was .75, making the number closer to 50501 than to 50500, the result of the
cast is still 50500.

Decimal to Decimal Conversions

Casting from a decimal at one precision level to a decimal at a lesser precision


level causes the system to round the result to the nearest value displayed at the
new precision level.

SELECT CAST(6.74 AS DEC(2,1));


Result: 6.7 (Drops precision)

SELECT CAST(6.75 AS DEC(2,1));


Result: 6.8 (Rounds up to even number)

SELECT CAST(6.85 AS DEC(2,1));


Result: 6.8 (Rounds down to even number)
Character to Character Conversions

SELECT CAST(last-name AS CHAR (5))


FROM employee
WHERE department_number = 401;
last_name
------------
Johns
Trade

As you can see from the example above, CAST can take the CHAR(20) last_name
data field from the employee table and convert it to a CHAR(5) data type. The
values displayed as a result of this query are truncated to five characters or
padded with trailing blanks up to five characters (if there are less than five
characters to start with).

Alternative Syntax

In current and previous versions of Teradata, data type conversions can also be
done without the CAST function as seen here:

SELECT last_name (CHAR (5)) FROM employee;

This type of conversion syntax is considered shorthand and is not ANSI standard.

Casting Attributes

In addition to simple CASTing, Teradata allows you to specify data attributes as


well as data types in your CAST.

SELECT CAST(last_name AS CHAR(5) UPPERCASE)


FROM employee
WHERE department_number = 401;
last_name
------------
JOHNS
TRADE

Things To Notice:

 The preceding example would return an error in an ANSI Mode session.


 Truncation of character strings is not permitted in an ANSI Mode CAST
expression.

Lab

Try It! For this set of lab questions you will need information from the
Database Info document.

To start the online labs, click on the Telnet button in the lower
left hand screen of the course. Two windows will pop-up: a
BTEQ Instruction Screen and your Telnet Window. Sometimes
the BTEQ Instructions get hidden behind the Telnet Window.
You will need these instructions to log on to Teradata.

Be sure to change your default database to the


Customer_Service database in order to run these labs.

Click on the buttons to the left to see the answers.

Answers: A. In a single SELECT statement, display the current DATE,


Lab A TIME and USER.
Lab B
Lab C Display the date 365 days from today.
Lab D
Lab E B. Create a report that gives the literal value "Math
Function" as its first column, the numeric value 1 as its
second column, and the calculation 2*3+4*5 as its third
column. Note the results. Modify this request to include
parentheses around the 3+4.

Resubmit the request. Note the difference in the result.

C. Some employees are getting raises. The department


401 manager is interested in what salaries would be if
each employee received a 10 percent increase. List the
first 10 characters of the last name, current salary, and
salary after the raise for the employees in department
401. Rank them in descending order by salary.

Submit again using EXPLAIN to look at how Teradata


will process this query.
Note: This lab is used again for exercise D.

D. Results of exercise C left management a bit shaken.


They are considering instead a flat $500.00 per
employee raise. Modify lab C to include this new
estimated salary as well as the 10% increase for
comparison. Include an additional column that tells the
net difference in dollars between the two options for
each employee. Rename this computed column by
inserting the two words AS Difference following the
computation. Take the current salary column out of the
report.
E. The government has ordered a special employment
demographics study. Generate a list of all employees
under 60 years old. Include last name (CAST the first
ten characters only), department number and computed
age in years.

Sort so that the youngest employees are listed first.

7.) Subqueries

Subqueries

Click on the link below to view the presentation on Subqueries.

Please Note: This is a narrated presentation. You may control the pacing of this
module by using the Pause button as well as other buttons available on the
screen duing the presentation.

Start Presentation

After viewing the presentation, return to this window and continue to the next
lab activity.

Lab

Try It! For this set of lab questions you will need information from the
Database Info document.

To start the online labs, click on the Telnet button in the lower
left hand screen of the course. Two windows will pop-up: a
BTEQ Instruction Screen and your Telnet Window. Sometimes
the BTEQ Instructions get hidden behind the Telnet Window.
You will need these instructions to log on to Teradata.

Be sure to change your default database to the


Customer_Service database in order to run these labs.

Click on the buttons to the left to see the answers for each lab
question.

Answers: A. Use EXISTS to determine if any job_codes are


Lab A unassigned to employees. Return ‘TRUE’ if there are
Lab B unassigned job codes.
Lab C B. List the last_name, first_name, and job code, for
Lab D employees with invalid job codes. Use a subquery to
Lab E establish a referential integrity check.
Lab F
Note: You may resolve this problem by using quantifiers
or by not using quantifiers. See if you can execute it
both ways.

C. Write a query to find employees who have invalid


Department Numbers. List the employee number, last
name, and the invalid department number. Note that
department numbers are valid only if they appear in the
department table, or they are NULL. This query performs
a check for referential integrity violations. If no rows are
found, what does that tell you?
D. List the customer number, customer name, and sales
representative's number for customers in California. Sort
by sales representative's number. Now do an EXPLAIN on
the request and note the total estimated time.

Hint: The location table contains both the customer


number and the state.

Note: This lab is used again for Lab B in the Inner Join
Module.

E. Find the names of any department manager whose job


code is 211100. List their employee number, last name,
department number, and job code. You will need to use
a subquery to identify which employees are department
managers.
Note: This lab is used again for Lab F below.

F. In Lab E, you found information about department


managers whose job code is 211100. In this lab, you
need to find information about employees who work for
the department managers with job code 211100. List the
employee's employee number, last name, department
number, and job code. To solve this problem, you'll need
to use nested subqueries. Try to do it without any AND's.
You may satisfy this request more than one way.

8.) Output Attributes

Objectives

After completing this module, you should be able to:

 Use TITLE to add a heading to your output that differs from the
column or expression name.
 Use AS to specify a name for a column or expression in a SELECT
statement.
 Use CHARACTERS to determine the number of characters in a string.
 Use TRIM to Trim blank characters or binary zeroes from data.
 Use FORMAT to alter the display of a column or expression.

Attributes and Functions

Attributes are characteristics which may be defined for columns, such as


titles and formats.

Functions are performed on columns to alter their contents in some way.

Expressions are columns and/or values combined with mathematical


operators. (i.e. Col1 + Col2 + 3).

Attributes for columns and expressions include the following:

AS Provides a new name for a column. ANSI


TITLE Provides a title for a column. Teradata
Extension
FORMAT Provides formatting for a column. Teradata
Extension

Functions for columns and expressions include the following:

CHARACTERS Count the number of characters in a Teradata


column. Extension
TRIM Trim the trailing or leading blanks or ANSI
binary zeroes from a column.

AS: Naming A Column or Expression

The AS clause:

 Assigns a temporary name to a column or expression.


 Can be referenced elsewhere in the query.
 Will default column headings to the newly assigned name.
 Use of Keyword AS is optional and may be omitted.

SELECT last_name
,first_name
,salary_amount / 12 AS monthly_salary
FROM employee
WHERE department_number = 401
ORDER BY monthly_salary;
last_name first_name monthly_salary
----------- ----------- --------------------
Johnson Darlene 3025.00
Trader James 3154.17

Note: Once you have renamed a column with the AS clause you may re-use that
name within your SQL statement. Renaming does not prevent you from using
any of the other methods we have discussed in your statement, for example:

order by salary_amount/12
order by salary_amount
order by 3 (using the positional reference)

Teradata Extensions

The Teradata RDBMS still supports the following form of specifying a name for a
column or expression:

<col or expression> (NAMED <name>)

This extension was introduced in a previous release.

The Teradata Equivalent to the previous example is:

SELECT last_name
,first_name
,salary_amount / 12 (NAMED monthly_salary)
FROM employee
WHERE department_number = 401
ORDER BY monthly_salary

Warning! NAMED is the old way of renaming a column for output display. AS is
the new method. Currently, both attributes work. In the future, support for the
NAMED attribute will disappear. Since the Teradata extension described above
provides equivalent functionality to the ANSI compliant version, all existing
Teradata SQL applications that use this form to name a column or expression
should be updated to use the ANSI compliant form (AS).

TITLE Attribute

The TITLE attribute allows you to rename columns for output with headings
that may contain multiple lines and/or blanks. Column headings may stack up
to three levels.

SELECT last_name
,first_name
,salary_amount / 12 (TITLE 'MONTHLY // SALARY')
FROM employee
WHERE department_number = 401
ORDER BY 3;
MONTHLY
last_name first_name SALARY
----------- ----------- ------------
Johnson Darlene 3025.00
Trader James 3154.17

Column heading justification on titles is determined by the data type of the


column. In our example, the words "MONTHLY" and "SALARY" are right-
justified because that is the default justification for DECIMAL values contained
in that column.

The new title must appear between single quotes ( ' ) in the TITLE phrase.
The // is used to represent a line break, causing the stacking. You can do the
same thing with AS, which is the ANSI standard. Literal strings must be
enclosed with double quotes (") when using AS.

SELECT last_name
,first_name
,salary_amount / 12 AS "MONTHLY // SALARY"
FROM employee
WHERE department_number = 401
ORDER BY 3;
MONTHLY
last_name first_name SALARY
----------- ----------- ------------
Johnson Darlene 3025.00
Trader James 3154.17

CHARACTERS Function

The CHARACTERS function is a Teradata-specific function which counts the


number of characters in a string. It is particularly useful for working with
VARCHAR fields where the size of the string can vary from row to row. In the
following example, first_name is a VARCHAR field. In order to determine which
employees have more than five characters in their name, we apply the
CHARACTERS function to the first_name column.

Problem

To find all employees who have more than five characters in their first name.

Solution

SELECT first_name
FROM employee
WHERE CHARACTERS (first_name) > 5;
first_name
------------
Loretta
Darlene
Arnando

Characters also may be abbreviated to CHAR or CHARS (e.g. "WHERE CHAR


(first_name) > 5").

The ANSI-standard version of this function (CHARACTER_LENGTH) may also be


used.

TRIM Function

Use the TRIM function to suppress leading and/or trailing blanks in a CHAR
column or leading and/or trailing binary zeroes in a BYTE or VARBYTE column.
TRIM is most useful when performing string concatenations.

There are several variations of the TRIM function:


TRIM ([expression]) leading and trailing blanks/binary
zeroes
TRIM (BOTH FROM [expression]) leading and trailing
blanks/binary zeroes
TRIM (TRAILING FROM[expression]) trailing blanks/binary zeroes
TRIM (LEADING FROM[expression]) leading blanks/binary zeroes

Problem

List the employees who have exactly four characters in their last name. The
data type of last_name is CHAR(20).

Solution 1

SELECT first_name
,last_name (TITLE 'last')
FROM employee
WHERE CHAR (TRIM (TRAILING FROM last_name)) = 4;

Solution 2

SELECT first_name
,last_name(TITLE 'last')
FROM employee
WHERE CHAR(TRIM(last_name))=4;

Results of either solution:

first_name last_name
----------- -----------
Loretta Ryan
James Daly

Note: When TRIM is specified with no additional directives, both leading and
trailing blanks are trimmed.

Using TRIM with Concatenation Operator

The || (double pipe) symbol is the concatenation operator that creates a new
string from the combination of the first string followed by the second.

Example 1:
Concatenating of literals without the TRIM function:

SELECT ' Jones ' || ','


|| ' Mary ' AS Name;

Name
------------------------
Jones , Mary

Example 2:

Concatenating of literals with the TRIM function:

SELECT TRIM(BOTH FROM ' Jones ')|| ','


|| TRIM(BOTH FROM ' Mary ')AS Name;

Name
------------
Jones,Mary

Using TRIM with Other Characters

Using TRIM with Other Characters

TRIM may also be used to remove characters other than blanks and binary
zeroes. Using the TRIM function format in the following examples, any defined
character(s) may be trimmed from a character string.

Example 1:

SELECT TRIM(BOTH '?' FROM '??????PAUL??????') AS Trim_String;

Trim_String
----------------
PAUL

Example 2:

SELECT TRIM(LEADING '?' FROM '??????PAUL??????') AS Trim_String;

Trim_String
----------------
PAUL??????

Example 3:

SELECT TRIM(TRAILING '?' FROM '??????PAUL??????') AS Trim_String;

Trim_String
----------------
??????PAUL

FORMAT Phrase

The FORMAT phrase can be used to format column output and override the
default format. For example:

SELECT salary_amount (FORMAT '$$$,$$9.99')


FROM employee
WHERE employee_number = 1004;

salary_amount
---------------
$36,300.00

The five dollar signs ($) in front of the FORMAT operand indicate that we want
to float the leading dollar sign until we hit the first significant digit. For
example, if the amount had been 6300.00, it would have been displayed as
$6,300.00.

Additional examples using the format (FORMAT '$$$,$$9.99)

Amount Display Notes

100105.25 ********* Mask cannot be applied


- value covers format
completely.

Dollar sign appears to


6300.00 $6,300.00 left of the most
significant digit.

.63 $0.63 Leading zero, because


the 9's in the mask
force the display of a
digit (or a zero, if there
is not one).
Fails, because this
3,336,300.00 ********** number is too large for
the mask.

Things To Notice

 Formats must provide for enough characters to contain the numeric


expression and also the specified format characters.
 Overflow conditions are represented by a string of asterisks.
 FORMAT is not ANSI compliant.

FORMAT allows you to format column output for a calculation. The format
character 'Z' is used to represent leading zero suppression. It works similarly
to the '$' in that it floats to the first significant digit.

Problem

Management has decided to give employee 1004 a $1,000 raise and wants to
know what percent the increase will be:

Solution

SELECT (1000/salary_amount) * 100 (FORMAT 'ZZ9%') AS "Increase


Percentage"
FROM employee
WHERE employee_number = 1004;

Increase Percentage
----------------------
3%

FORMAT Characters

The following FORMAT characters are available:

$ Fixed or floating dollar sign.


9 Decimal digit (no zero suppress).
Z Zero-suppressed decimal digit.
, Comma. Inserted where specified.
. Decimal point position.
- Dash character. Inserted where specified.
/ Slash character. Inserted where specified.
% Percent character. Inserted where specified.
X Character data. Each X represents one character.
G Graphic data. Each G represents one logical (double byte)
character.
B Blank data. Insert a space at this point.

Examples

FORMAT '999999' Data: 08777 Result: 008777


FORMAT 'ZZZZZ9' Data: 08777 Result: 8777
FORMAT '999-9999' Data: 6495252 Result: 649-5252
FORMAT 'X(3)' Data: 'Smith' Result: Smi
FORMAT '$$9.99' Data: 85.65 Result: $85.65
FORMAT '999.99' Data: 85.65 Result: 085.65
FORMAT 'X(3)' Data: 85.65 Result: Error

The final example produces an error because numeric data cannot be


formatted using a character string format. It must first be converted or 'cast'
to a character string before an 'X' type of format may be applied.

The $, 9, Z, X, G, and B symbols can be repeated in a FORMAT phrase either


by repeating them (e.g., XXX) or by listing them followed by a repetition
number (e.g., (X(3)).

The FORMAT mask can contain specifications for up to 18 digits of data plus
other insertion characters. If you needed to have 18 zero-suppressed decimal
digits, you could note it as Z(18) rather than ZZZZZZZZZZZZZZZZZZ.

DATE Formats

When dates are displayed as character strings, appropriate formats are


applied.

The Teradata default format is:


YY/MM/DD

The ANSI display format is:


YYYY-MM-DD

The recommended display format eliminates uncertainty about the century.


For example, in the case of:

09/04/28
It is unclear whether this format represents

April 28, 1909 or April 28, 2009

Let's look at some unambiguous DATE formats which show all four digits of the
year:

SYNTAX RESULT
FORMAT 'YYYY/MM/DD’ 2009/04/28
FORMAT 'DDbMMMbYYYY' 28 Apr 2009
FORMAT 'mmmBdd,Byyyy' Apr 28, 2009
FORMAT 'DD.MM.YYYY' 28.04.2009

DATE format syntax is not case-sensitive.

The following formats are available for date displays:

Y4: 4-Digit year (Same as YYYY)


YY: 2-Digit year
M4: Long Month - i.e. fully defined name for month (Same as MMMM)
M3: Short Month - i.e., abbreviated name for month (Same as MMM)
MM: 2-Digit month
DD: 2-Digit day of month
D3: 3-Digit day of year (Julian date) (Same as DDD)

Example

SELECT CURRENT_DATE (FORMAT 'M3-DD');

Date
-------------
Mar-01

Note: Date formatting options may also use expanded syntax (i.e., MMM-DD).

Example

SELECT CURRENT_DATE (FORMAT 'Y4:M4:D3');

Date
------------------
2010:March:060

Note: The date is the 60th day of the year 2010.

FORMATing DATE in an SQL SELECT Statement

Use the FORMAT phrase within a SELECT statement as follows:

SELECT last_name
,first_name
,hire_date (FORMAT 'mmmBdd,Byyyy')
FROM employee
ORDER BY last_name;

last_name first_name hire_date


-------------------- ------------------------------ ------------
Johnson Darlene Oct 15, 1976
Kanieski Carol Feb 01, 1977
Ryan Loretta Oct 15, 1976
Stein John Oct 15, 1976
Trader James Jul 31, 1976
Villegas Arnando Jan 02, 1977

Sorting By Formatted Columns

Problem

A department manager wants to take employees to lunch on their birthdays.


We need to know the month and day of each employee's birthday. The
manager would like the list sorted in the order in which the birthdays will
occur.

Solution 1 - Using FORMAT

SELECT last_name
,first_name
,birthdate (FORMAT 'mmdd') AS birthday
,birthdate AS whole_date
FROM employee
WHERE department_number = 401
ORDER BY 3;

last_name first_name birthday


whole_date
-------------------- ------------------------------ -------- --
--------
Rogers Frank 0423
35/04/23
Brown Alan 0809
44/08/09
Johnson Darlene 0423
46/04/23
Trader James 0619
47/06/19
Hoover William 0114
50/01/14
Machado Albert 0714
57/07/14
Phillips Charles 0810
63/08/10

This solution does not produce the desired sorted result. Note that Brown's
birthday sorts between Rogers and Johnson whereas ideally, it should follow
them. The ORDER BY 3 sorts on the full internal representation of the
birthdate column (i.e., year, month and day). The FORMAT specification
suppresses the year in the viewable output but not in the sort.

Solution 2 - Using MODULO

The MODULO function works similarly to long division. Just as when we divide
7 by 3, we get a quotient of 2 and a remainder of 1. MODULO does exactly
the opposite. 7 MOD 3 discards the quotient and keeps only the remainder.
Thus, 7 MOD 3 = 1.
SELECT last_name
,first_name
,birthdate MOD 10000 (FORMAT '9999')
AS birthday
,birthdate AS whole_date
FROM employee
WHERE department_number = 401
ORDER BY 3;

last_name first_name birthday


whole_date
-------------------- ------------------------------ -------- --
--------
Hoover William 0114
50/01/14
Johnson Darlene 0423
46/04/23
Rogers Frank 0423
35/04/23
Trader James 0619
47/06/19
Machado Albert 0714
57/07/14
Brown Alan 0809
44/08/09
Phillips Charles 0810
63/08/10

Why do we see different results in ordering the results? FORMAT is a mask


which does not convert the underlying data. MOD is an arithmetic function
which does convert the data before the FORMAT is applied. Here we get the
desired sorted output. This is because when we MOD 440809 BY 10000, the
result is a new integer: 0809. The sort happens on these four digits only.

Using FORMAT With ODBC-based Applications

The FORMAT option, when used, must be applied to data represented as


character strings. Thus, when numerics or dates are concerned, the formatting
only takes place if the data is first converted to character. Because this happens
automatically in BTEQ, it can be surprising when using ODBC-based applications
when a FORMAT appears to be not working. The conversion to character data
must be explicitly done when using ODBC-based applications like SQL
Assistant.

Using FORMAT With SQL Assistant


Things To Notice:

 Any specified FORMAT must always be applied to a character string.


 Thus, a conversion from any numeric to character is required.
 BTEQ does automatic character conversion prior to applying a format.
 ODBC does not do it automatically, thus the user must explicitly request
the conversion.
 If the column is not a character data type, the FORMAT will be ignored.
 FORMAT syntax must precede the specified conversion data type syntax.

Using the EXTRACT Function

Extracting From Current Date

The EXTRACT function allows for easy extraction of year, month and day from
any DATE data type. The following examples demonstrate its usage.

Query Result
SELECT DATE; /* March 20,2001 */ 01/03/20 (Default format)
SELECT EXTRACT(YEAR FROM DATE); 2001
SELECT EXTRACT(MONTH FROM DATE); 03
SELECT EXTRACT(DAY FROM DATE); 20

Date arithmetic may be applied to the date prior to the extraction. Added
values always represent days.

Query Result
SELECT EXTRACT(YEAR FROM DATE +
2002
365);
SELECT EXTRACT(MONTH FROM DATE +
04
30);
SELECT EXTRACT(DAY FROM DATE + 12); 01

Note: CURRENT_DATE is the ANSI standard for today's date and may be used
in place of DATE, which is Teradata specific.

Extracting From Current Time

The EXTRACT function may also be applied against the current time. It permits
extraction of hours, minutes and seconds. The following examples
demonstrate its usage.

Query Result
SELECT TIME; /* 2:42 PM */ 14:42:32 (Default format)
SELECT EXTRACT(HOUR FROM TIME); 14
SELECT EXTRACT(MINUTE FROM TIME); 42
SELECT EXTRACT(SECOND FROM TIME); 32

Time arithmetic may be applied prior to the extraction. Added values always
represent seconds.

Query Result
SELECT EXTRACT(HOUR FROM TIME +
14
20);
SELECT EXTRACT(MINUTE FROM TIME +
42
20);
SELECT EXTRACT(SECOND FROM TIME +
52
20);
SELECT EXTRACT(SECOND FROM TIME +
Invalid Time
30);
Note: CURRENT_TIME is the ANSI standard for current time and may be used
in place of TIME, which is Teradata specific. While TIME is a Teradata function,
it does not have the intelligence of the DATE data type, thus adding 30
seconds to 32 seconds produces an invalid 62 for the seconds portion. For
true time and timestamp arithmetic, the TIME and TIMESTAMP data types are
needed. These capabilities are covered in the Advanced SQL course.

Truncating CHARACTER Columns

The FORMAT phrase can create the appearance of truncating a character


column or expression.

The FORMAT phrase controls the display of the result but does not change the
underlying data in any way.

Example

SELECT last_name
,first_name
,first_name (FORMAT 'X')
FROM employee
WHERE last_name = 'Brown'
ORDER BY 3;
last_name first_name first_name
----------- ----------- -----------
Brown Alan A
Brown Allen A

Question

Does this method sort on just the first initial?

Answer

No, it sorts on the full first name value.

Problem

Show the last name, first name, and first initial of all employees named
Brown. Sequence by the first initial.

SELECT last_name
,first_name
,CAST (first_name AS CHAR(1))
FROM employee
WHERE last_name = 'Brown'
ORDER BY 3;
last_name first_name first_name
----------- ----------- -----------
Brown Allen A
Brown Alan A

Question

Does this method sort on the first initial only?

Answer

Yes, because we have actually CAST the first_name to a new data type of
CHAR(1).

Note: Both of the above examples would return an error if run in an ANSI
mode session. This is because ANSI mode does not support character
truncation as part of a CAST operation.

Attribute Functions

Attribute functions are Teradata extensions which return descriptive


information about the operand, which may be either a column reference or
general expression.

The functions available for attribute information are the following:

 TYPE
 TITLE
 FORMAT
 NAMED
 CHARACTERS

Here are some examples of how these functions work:

Query Results
SELECT DISTINCT TYPE (job_code) FROM
job; INTEGER
SELECT DISTINCT TITLE (job_code)FROM job_code
job;
SELECT DISTINCT FORMAT (job_code)FROM (10)9
job;
SELECT DISTINCT NAMED (job_code)FROM job_code
job;
SELECT DISTINCT CHARACTERS(last_name) 20
FROM employee;

Note: DISTINCT is used in these queries to reduce output to a single row of


information per query. If DISTINCT is not used, the information is repeated
once for each row in the table.

Lab

Try It! For this set of lab questions you will need information from
the Database Info document.

To start the online labs, click on the Telnet button in the


lower left hand screen of the course. Two windows will pop-
up: a BTEQ Instruction Screen and your Telnet Window.
Sometimes the BTEQ Instructions get hidden behind the
Telnet Window. You will need these instructions to log on to
Teradata.

Be sure to change your default database to the


Customer_Service database in order to run these labs.

Click on the buttons to the left to see the answers.

Answers: A. The manager of department 401 needs a list of


Lab A employees for the department that includes last
Lab B name, hire date and bi-weekly salary (26 pay periods
Lab C per year) sorted descending by salary. Title the
Lab D computed salary as "Salary Amount". Format hire
date as an English abbreviation, followed by day and
Lab E
a four-digit year. Show salary with floating dollar
Lab F
signs, commas, and two decimal positions.
Remember: The salary column in the employee table
is the annual salary.

If you get ****** for salary amount, it indicates an


insufficient format for the size of the result. Be sure
to provide enough places to the left of the decimal
point.

B. Select employee number and phone number from the


employee phone table. Edit phone number with a
hyphen between the third and fourth digits. Sort by
employee number. Use column titles "Employee" and
"Phone".
C. Print the employee number, names and ages of
department 301 employees. Name the computed
column "Age" and title the last name and first name
columns "Last Name" and "First Name". Sequence
ascending by age. Format first name as nine
characters.
D. Show the first 10 characters of the last name and
show the department number and hire date. Order
results by hire date.

Option 1: (Do if the current month is NOT


September, November, or December.) Find only
employees whose date-of-hire anniversary is this
month, regardless of what year they were hired.

Option 2: (Do if the current month IS September,


November or December. Find out which employees
had an anniversary month four months ago.

E. Modify Lab D to include an additional column on the


report containing the three-lettered English
abbreviation for the month. Title this column
"month". Notice that the month column is right-
justified even though it appears alphabetic. With
FORMAT, underlying data controls alignment.
F. Select all employees who work in department 501.
Show last and first names (both formatted as 8
positions), and three date columns: one for month of
hire as a computed value titled "month"; another for
English abbreviation of hire month without a title; and
a third for year-of-hire as a 4-digit value with a title
of "year".

Sort using numeric designators from the SELECT


clause. Do it twice. Note sort results. Submit with sort
on the extracted month column. Sort again on the full
date.

9.) Inner Joins

Objectives

After completing this module, you should be able to:

 Perform an Inner Join on two or more tables.


 Perform two special cases of an Inner Join:
o A Cartesian product join.
o A Self join.
 Use an alias as a temporary name for a Table or View.
 Determine when to use a subquery versus a Join.

Join

A join is a technique for accessing data from more than one table in an
answer set. Tables are joined according to columns they have in common. A
join between the employee table and the department table could be done
according to department number. An example of an inner join will be seen on
the next screen:

Joins may access data from tables, views or a combination of the two.

Types of Joins

Inner Rows which match based on join criteria.


Outer* Rows which match and those which do not.
Cross Each row of one table matched with each row of another.
Self Rows matching other rows within the same table.

* Outer Joins are discussed in a separate section of the SQL WBT.

Our main focus in this module will be Inner Joins.

Inner Join Problem

To get a report that includes employee number, last name, and department
name, join the employee table and the department table.

Department number is the common column that determines the way data in
these two tables will be joined. Most often joined columns are related to each
other as primary and foreign keys.

Inner Join Solution


employee_number last_name department_name
-------------------- ----------- --------------------

1006 Stein research and development


1008 Kanieski research and development

1005 Ryan education

1004 Johnson customer support

1007 Villegas education


1003 Trader customer support

. . .

. . .

. . .

We fully qualified every column referenced in our SELECT statement to include the
table that the column is in ( e.g., employee.employer_number). It is only
necessary to qualify columns that have identical names in both tables (i.e.,
department_number).

The ON clause is used to define the join condition used to link the two tables.

Defining and Using Alias Names

An alias is a temporary name for a TABLE or VIEW defined in the FROM clause. It
can be useful for abbreviating long table names and is 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;
employee_number last_name department_name
------------------- ---------- --------------------
1006 Stein research and development
1008 Kanieski research and development
1005 Ryan education
1004 Johnson customer support
1007 Villegas education
1003 Trader customer support

Note: The "e" in the FROM clause is what sets up "e" as the employee table alias.
Similarly, the "d" sets up the department table alias. Alias names can be up to
30 characters.

Aliases can be used in the SELECT part of the statement even though SELECT
appears before FROM in a statement. Once an alias has been established, it
should be used consistently thoughout the query. Using the original table name
as a qualifier instead of the alias may produce unexpected results as we shall see
in a later example.

Cross Joins

A Cross Join is a join that requires no join condition (Cross Join syntax does not
allow an ON clause). Each participating row of one table is joined with each
participating row of another table. The WHERE clause restricts 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;
employee_number department_number
-------------------- ----------------------
1008 301
1008 501
1008 402
1008 201
1008 302
1008 600
1008 401
1008 100
1008 403

The employee table has 26 rows. The department table has 9 rows. Without the
WHERE clause, we would expect 26 x 9 = 234 rows in our result set. With the
constraint that the employee_number must equal 1008 (which only matches one
row in the employee table), we now get 1 x 9 = 9 rows in our result set.

Cross Joins by themselves often do not produce meaningful results. This result
shows employee 1008 associated with each department. This is not meaningful
output. Cross joins can however produce useful information as will be seen in the
following pages.

Cartesian Product

A completely unconstrained Cross Join is called a Cartesian product. A Cartesian


product results when a CROSS JOIN is issued without a WHERE clause. In this
case, each row of one table is joined to each row of another table.

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. The output of a Cartesian product is often not
meaningful however they do have useful application as we shall see.

Cartesian products may also result accidentally from an INNER JOIN with
improper aliasing or missing join conditions.

Useful Cartesian Products

There are some real-world uses for Cartesian product joins. One important use is
to benchmark system performance with large data throughputs. Cartesian
products make it easy to generate very large answer sets.

Example
Any query requiring all elements of one table to be compared to all elements of
another is a candidate for a Cartesian product using the CROSS JOIN syntax.

As demonstrated in the above diagram, a CROSS JOIN can be useful to an airline


for comparing all possible combinations of cities in order to evaluate:

 flight plan information,


 passenger rate structures,
 mileage awards

Inner Joins on Multiple Tables

Historically, a join could have up to 16 participating Tables or Views. Since


Teradata V2R2.1, the join limit has been increased to 64 participating Tables or
Views. The number of participating Tables/Views determines the number of
required join conditions. An n-table join requires n-1 join conditions. In this
example, three tables are joined, thus requiring two join conditions (two ON
clauses). Omitting any 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;
last_name department_name description
----------- -------------------- ------------
Daly software support Manager - Software Supp
Runyon marketing sales Manager - Marketing Sales
Trainer president Corporate President
Brown customer support Dispatcher
… … …

Accidental Cartesian Products

An accidental Cartesian product can result from an Inner Join with improper
aliasing:

SELECT employee.employee_number
,d.department_name
FROM employee e INNER JOIN
department d
ON e.department_number = d.department_number;

We forgot to use the "e" alias in the SELECT statement. The parser sees that "e"
needs to be joined with "d". That's two tables and one join. So far, so good. Then
the parser sees a reference to employee and views it as a third table. We now
have three tables and only one join, resulting in an unintended Cartesian
product.

A Cartesian product also may 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;

In the above example, since 3 = 3 is always true, every row meets this
condition. Every row in the department table is joined with every row in the
employee table. We probably do not want this result.

EXPLAIN all queries before allowing them to run in a production environment!


Please see the section on EXPLAIN at the end of this module.

If your EXPLAIN statement estimates a huge number of rows or hours to


complete, it could mean that your query will unintentionally produce a Cartesian
product.

Self Joins

A self join occurs when a table is joined to itself. Which employees share the
same surname Brown and to whom do they report?

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';

Result

Emp Emp Mgr Mgr


First Name Last Name First Name Last Name
Allen Brown Loretta Ryan
Alan Brown James Trader

Would the results differ if the last condition was:

WHERE employee.last_name = 'Brown' ?

 Next time you log on for Lab, try it and see.

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.
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%';

Using a SUBQUERY

SELECT first_name
,last_name
,department_number
FROM employee
WHERE department_number IN
(SELECT department_number FROM department
WHERE department_name LIKE '%Research%');

Result

first_name last_name department_number


------------ ----------- ---------------------
Carol Kanieski 301
John Stein 301
Ron Kubic 301

Note that in some cases, either a join or a subquery may be used to produce the
same result.
Use EXPLAIN to Understand a Join

Use EXPLAIN to see how the database will execute your query. EXPLAIN is
especially useful for checking to see that you are not creating an unintended
Cartesian product.

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.
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 with low confidence 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 (-1 ). Spool 2 and CUSTOMER_SERVICE.department are joined
using a merge join, with a join condition of
("Spool_2.department_number=CUSTOMER_SERVICE.department.departme
nt_number"). The result goes into Spool 1, which is built locally on the
AMPs. The size of Spool 1 is estimated with no confidence 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.

EXPLAIN a Subquery
You can also use EXPLAIN against your subqueries.

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 lock
CUSTOMER_SERVICE.department for read.
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 with low confidence. The
estimated time for this step is 0.03 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.departme
nt_number"). The result goes into Spool 1, which is built locally on the
AMPs. The size of Spool 1 is estimated with index join confidence to be 22 to
24 rows. Estimated time for this step is to 0.21 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.23 seconds.

Question

The query on this page and the one from the Join on the previous page produce
equivalent results. How could you compare their expected performance on the
system?

One way is to compare some of the basic characteristics divulged by the EXPLAIN
.The Join query took six steps and estimated that it would return 24 rows and take
approximately 0.23 seconds to complete.

In comparison, the Subquery took five steps, estimated that it would return 28
rows and take approximately 0.24 seconds to complete.

The two implementations of this query are roughly equivalent from a performance
standpoint.

Lab

Try It! For this set of lab questions you will need information from the
Database Info document.

To start the online labs, click on the Telnet button in the lower
left hand screen of the course. Two windows will pop-up: a
BTEQ Instruction Screen and your Telnet Window. Sometimes
the BTEQ Instructions get hidden behind the Telnet Window.
You will need these instructions to log on to Teradata.

Be sure to change your default database to the


Customer_Service database in order to run these labs.

Click on the buttons to the left to see the answers.

Answers: A. List the employee number, last name, salary, and job
Lab A description of all employees except the President. (The
Lab B President is the only employee assigned to Department
Lab C 100.) Format last name as 9 characters and description
Lab D as 20 characters. Sort by employee number within job
description.
Lab E
B. Modify Lab D from the Subquery module to use a join
instead of a subquery to select information about
California customers. EXPLAIN the request and note the
total estimated time. Compare with the total estimated
time from Lab D in the Subquery module. Which is more
efficient: the join or the subquery?
C. Produce a report showing employee number,
department number and manager’s last name for all
employees hired before Jan 1, 1978. Sort by
department number.
D. Do an EXPLAIN statement using CROSS JOIN on the
employee and job tables. Select job code, job
description and employee last name.
E. Management has a request. They need the last name,
department name, job description, and phone number
of all employees in the 213 area code with job code
412101. Use table name aliases for your joins. Order by
last name.

You might want to use EXPLAIN with this exercise, to


see what processing takes place.

Note: Check your quick reference page to be sure you


are accessing the correct tables.

10.) Outer Joins

Outer Joins

Click on the link below to view the presentation on Outer Joins.

Please Note: This is a narrated presentation. You may control the pacing of this
module by using the Pause button as well as other buttons available on the
screen duing the presentation.

Start Presentation

After viewing the presentation, return to this window and continue to the next
lab activity.

Lab

Try It! For this set of lab questions you will need information from
the Database Info document.

To start the online labs, click on the Telnet button in the lower
left hand screen of the course. Two windows will pop-up: a
BTEQ Instruction Screen and your Telnet Window. Sometimes
the BTEQ Instructions get hidden behind the Telnet Window.
You will need these instructions to log on to Teradata.

Be sure to change your default database to the


Customer_Service database in order to run these labs.

Click on the buttons to the left to see the answers.

Answers: A. List the last name, job code and job description of all
Lab A employees. Cast last name as 9 characters, and job
Lab B description as 20 characters. Sort by last name. Also,
Lab C include employees who have an invalid or null
Lab D job_codes. Use outer join syntax to accomplish this.
B. Show the last name, job description and department
name of all employees with valid departments and
valid job codes. Order by last name. Format last name
as 9 characters, job description as 20 characters and
the department name as 13 characters.
C. Modify exercise B to include employees with valid
departments but without valid job codes.
D. Modify exercise B to include unassigned job codes.

11.) Set Operations

Objectives

After completing this module, you should be able to:

 Use the UNION operator.


 Use the INTERSECT operator.
 Use the EXCEPToperator.

Set Operators

The following are graphic representations of the three set operators, INTERSECT,
UNION and EXCEPT. All are ANSI-compliant operators.

INTERSECT

The INTERSECT operator returns rows from multiple sets which share some
criteria in common.
UNION

The UNION operator returns all rows from multiple sets, displaying duplicate rows
only once.

EXCEPT

The EXCEPT operator subtracts the contents of one set from the contents of
another.

Note: Using the Teradata keyword ALL in conjuction with the UNION operator
allows duplicate rows to remain in the result set.

UNION Operator

Before the introduction of the OUTER JOIN feature, The UNION operator provides
functionality similar to the OUTER JOIN feature. UNION is still a viable feature,
however. Here are some rules for its usage:

All SELECT clauses:

 Must have the same number of expressions.


 Corresponding expressions must have compatible data types.

The first SELECT statement:

 Determines output FORMAT.


 Determines output TITLE.

The last SELECT statement:


 Contains the ORDER BY clause for the entire result when applicable.
 Uses numeric designators for the ORDER BY columns.

Problem

Show manager 1019 identifying him as the manager, show his employees and
identify each of them as an employee.

Solution

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
;

Result

employee
first_name last_name type
Carol Kanieski employee
Ron Kubic manager
John Stein employee

INTERSECT Operator

Problem

Create a list of all department managers who are assigned subordinate


employees. Note that not all department managers have subordinates and not all
managers with subordinates are department managers.

Solution

SELECT manager_employee_number
FROM employee
INTERSECT
SELECT manager_employee_number
FROM department
ORDER BY 1
;

Result

manager_employee_number
801
1003
1005
1011
1017
1019
1025

EXCEPT Operator

The EXCEPT operator is ANSI intermediate compliant. It will be flagged as non-


entry level by the SQL flagger:

*** SQL warning 5811 MINUS of queries is not in entry level ANSI.

This flagged message refers to "MINUS" because the Teradata-compatible


synonym for EXCEPT is MINUS. Use the EXCEPT operator rather than MINUS
because although both provide the same functionality, EXCEPT is ANSI compliant.

Problem

To list all department managers who do not have subordinates.

Solution
SELECT manager_employee_number
FROM department
EXCEPT
SELECT manager_employee_number
FROM employee
ORDER BY 1
;

Result

manager_employee_number
1016
1099

SET Operators - Additional Rules

Set operators may be used in most SQL constructs but cannot contain a WITH or
WITH...BY clause. Set operators are evaluated in order of precedence, as
follows:

 INTERSECT
 UNION
 EXCEPT from left to right

Evaluation order may be manipulated with parentheses.

 Each SELECT statement must have a FROM table_name.


 The GROUP BY clause does not apply to the result set as a whole.
 Duplicates are eliminated unless the ALL option is used.

Lab

Try It! For this set of lab questions you will need information from
the Database Info document.

To start the online labs, click on the Telnet button in the lower
left hand screen of the course. Two windows will pop-up: a
BTEQ Instruction Screen and your Telnet Window.

Sometimes the BTEQ Instructions get hidden behind the


Telnet Window. You will need these instructions to log on to
Teradata.

Be sure to change your default database to the


Customer_Service database in order to run these labs.

Click on the buttons to the left to see the answers.

Answers: A. Use the UNION operator to generate a complete list of


Lab A all phone numbers belonging to a location or to an
Lab B employee in the 415 area code. Designate a category
Lab C to which each row belongs. Entitle this literal column
"owner". Sort the report by phone number. Hyphenate
all phone numbers.
B. Find the valid employee numbers for department level
managers. You will be doing a referential integrity
check between department and employee tables.
Accomplish this using a subquery, then again using the
INTERSECT operator. Use EXPLAIN to compare
efficiency and optimization choices. Which is better?
C. Produce a list of all job codes which are currently
assigned to employees but which are invalid. Title the
column 'INVALID JOB CODES' and use the EXCEPT
operator to solve the problem.

12.) Creating Tables and Indexes

Objectives

After completing this module, you should be able to:

 CREATE, DROP, or ALTER a table.


 CREATE, DROP, or ALTER an index.
 CREATE, DROP, or ALTER table attributes.

Data Definition Language

Data Definition Language (DDL) is used by SQL to create, modify, and remove
object definitions:

The Teradata Database implements separate DDL statements for different


objects.
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

Join Indexes CREATE JOIN INDEX


DROP JOIN INDEX

Triggers CREATE TRIGGER


ALTER TRIGGER
DROP TRIGGER

Stored CREATE PROCEDURE


Procedures REPLACE PROCEDURE
DROP PROCEDURE

In this module we will look at creating tables and indexes only.

CREATE TABLE Elements

When executed, the CREATE TABLE statement creates and stores the table
structure definition in the Data Dictionary (DD).

The CREATE TABLE statement allows you to create:

 TABLE options.
 COLUMN definitions.
 TABLE level constraints.
 INDEX definitions.

Note: We cover Table level constraints in the Advanced SQL course. Our
discussion here will focus on table options, column definitions, and index
definitions.

CREATE <SET/MULTISET> TABLE employee


<Create Table Options>
<Column Definitions>
<Index Definitions>;

Element Definition

Create Table Options Specify physical attributes of table to include:

 Fallback.
 Journaling.

Column Definitions Define each column in the table.

Index Definitions Specify indexes for physical access to data.

CREATE TABLE Options

Teradata Extensions

Teradata DDL allows you to specify physical implementation options such as


fallback and permanent journal protection, datablocksize, and cylinder freespace
factor. You may define a primary index (different than the primary key) as well
as secondary indexes to improve physical access to data in the table.

Duplicate row options


- SET no duplicate rows allowed (Default)
- MULTISET duplicate rows allowed

Table protection options (Underlines indicate defaults)


- FALLBACK or NO FALLBACK PROTECTION
- BEFORE JOURNAL (NO, SINGLE or DUAL)
- AFTER JOURNAL (NO, SINGLE (LOCAL or NOT LOCAL) or DUAL)
- WITH JOURNAL TABLE (tablename)

FALLBACK specifies that the system builds a duplicate copy of each row of the
table and stores it on a different (FALLBACK) AMP within the cluster.

JOURNAL specifies that the system stores BEFORE and /or AFTER images for each
changed row of the table in the specified permanent journal, providing disaster
recovery capability.

Space Management Options (Defaults are provided if not specified)

 FREESPACE - % cylinder freespace to maintain during loading operation


 DATABLOCKSIZE - maximum block size for multi-row data blocks

Example

CREATE TABLE table_1


,FALLBACK, NO JOURNAL
(field1 INTEGER
, field2 CHAR(10)
, field3 DEC(8,2))
;

COLUMN Definitions

Up to 2,048 columns may be defined in a single CREATE TABLE statement.

You may define the following aspects of each column:

Aspect Meaning
Column Name Name of the column

Data Type
Column data type (INTEGER, CHAR, etc.)

Data Type Attributes Column attributes such as:


DEFAULT, FORMAT, TITLE, NULL, CASESPECIFIC,
UPPERCASE

Column Storage
Column compression for nulls or for specific values
Attributes

Column-Level Column range of possible values, uniqueness, use as


Constraint Attributes a primary or foreign key
We will discuss each in detail in the following sections.

COLUMN Name & Data Type Choices

Column Data Types

Character CHAR, VARCHAR,


CHAR VARYING,
LONG VARCHAR

Numeric INTEGER, SMALLINT, BIGINT,


REAL, FLOAT, DOUBLE
PRECISION NUMERIC,
DECIMAL, BYTEINT,
DATE

Byte BYTE, VARBYTE

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 Attributes

DEFAULT Specify default value in place of null

WITH Specify use of system default value in place of null


DEFAULT

FORMAT Default display format


TITLE Default column title

NOT NULL Disallow nulls, value required

CASESPECIFIC Treat as case-specific for comparisons

UPPERCASE Shift to uppercase for storage

Example

CREATE TABLE emp_data


(employee_number INTEGER NOT NULL
,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/yyyy'
,salary_amount DEC(10,2)
,sex CHAR(1) UPPERCASE
);

The WITH DEFAULT option is a special case of the DEFAULT option. The
WITH DEFAULT phrase is converted by the Teradata database to a
DEFAULT option in which the default system value for that data type
becomes the value to use in place of null. For example, character
strings will be defaulted to spaces and numeric columns will default
to zeroes.

Retrieving Default Values

A DEFAULT function exists which permits the retrieval of the default value
assigned to a particular column. For example, assume we define a table as
follows:

CREATE TABLE TableX


(Col1 INTEGER,
Col2 INTEGER DEFAULT 10,
Col3 INTEGER DEFAULT 20,
Col4 CHAR(60));

We may retrieve the default values for any column by using the DEFAULT
function as follows:

SELECT DEFAULT(Col2), DEFAULT(Col3) FROM TableX;


Default(Col2) Default(Col3)
------------- -------------
10 20
10 20

Default values are returned in place of the normal column values. Note that two
rows are returned. This is because there are currently two rows in the table. One
row of output is returned for each existing row in the table. You may return a
single row by using the following syntax:

SELECT DISTINCT DEFAULT(Col2), DEFAULT(Col3) FROM TableX;

Default(Col2) Default(Col3)
------------- -------------
10 20

If there are no rows in the table, no default values will be returned.

If no default values are assigned to the specified column, then a null is returned.

COLUMN Storage Attributes

Teradata Extensions

The COMPRESS phrase allows values in one or more columns of a permanent table
to be compressed to zero space, thus reducing the physical storage space
required for a table.

The COMPRESS phrase has three variations:

Variation: What happens:

COMPRESS Nulls are compressed.

COMPRESS NULL Nulls are compressed.

COMPRESS Nulls and the specified <constant> value are


<constant> compressed.

Note: COMPRESS & COMPRESS NULL mean the same thing.

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'
.
.
.

In the first example, null department numbers will be compressed.

In the second example, both null and 'Savings' account types will be suppressed.
The value of 'Savings' is written in the table header for bank_account_data on
each AMP in the system.

Primary Key vs Primary Index

Primary Key (PK) - is defined as one or more columns used to uniquely identify
each row in a table. PKs are used in conjunction with foreign keys to define the
important column relationships in a database. PKs are always unique and cannot
be null. PKs are not known to the Teradata RDBMS as such. The Teradata
RDBMS implements a primary key as a unique index.

Primary Index - is defined as one or more columns used to distribute and


locate rows in a table. Choice of primary index will affect distribution, access and
performance. Oftentimes, but not always, the Primary Index and Primary Key are
the same. Indexes (primary or secondary) may be used to enforce uniqueness
(as in a PK) or to improve access. They may be unique or non-unique.
Uniqueness and primary key constraints will be discussed in more detail in Level
3.

Indexes may be any combination as seen in the following table:

Primary Secondary

UNIQUE UPI USI

NON-UNIQUE NUPI NUSI

Every table must have exactly one primary index.

The following table illustrates performance characteristics for SQL operations that
use indices.
Entries are listed in order from most desirable to least desirable in terms of
system resource use. They show the number of AMPs involved in each operation
and number of rows that could be returned.

#AMPS #ROWS

UPI 1 0 or 1

NUPI 1 Between 0-N


where N = any number > 0

USI 2 Between 0-1

NUSI All Between 0-N

Full table scan All Between 0-N

CREATE TABLE Example

The following example shows everything we have learned up to this point about
the CREATE TABLE statement.

CREATE TABLE MJ1.emp_data,FALLBACK,


NO BEFORE JOURNAL,
NO AFTER JOURNAL
(
employee_number INTEGER NOT NULL,
department_number SMALLINT,
job_code INTEGER COMPRESS ,
last_name CHAR(20) NOT CASESPECIFIC NOT NULL,
first_name VARCHAR(20) NOT CASESPECIFIC,
street_address VARCHAR(30) NOT CASESPECIFIC TITLE 'Address',
city CHAR(15) NOT CASESPECIFIC DEFAULT 'Boise'
COMPRESS 'Boise',
state CHAR(2) NOT CASESPECIFIC DEFAULT ' ',
birthdate DATE FORMAT 'mm/dd/yyyy',
salary_amount DECIMAL(10,2),
sex CHAR(1) UPPERCASE NOT CASESPECIFIC)

UNIQUE PRIMARY INDEX ( employee_number )


INDEX ( department_number );

Note: Employee number is a Unique Primary Index (UPI). The department


number is a Non-Unique Secondary Index (NUSI).

CREATE TABLE Rules


Any user may create a table in a given database, provided that they have the
'CREATE TABLE' privilege for that database.

For INDEX definition, if UNIQUE is not explicit, then the default is a non-unique
index. Similarly, if PRIMARY is not explicit, then the default is a secondary index.

Examples:

UNIQUE PRIMARY INDEX - UPI created


PRIMARY INDEX - NUPI created
UNIQUE INDEX - USI created
INDEX - NUSI created

DROP TABLE

To remove all data associated with a table, as well as the table structure
definition from the Data Dictionary, use the DROP TABLE statement.

Example

Drop the employee data table created in the previous example.

DROP TABLE emp_data;

 Deletes all data in emp_data.


 Removes the emp_data definition from the Data Dictionary. You must
recreate the table if you wish to use it again.
 Removes all explicit access rights on the table.

To remove all data associated with a table, without dropping the table definition
from the Data Dictionary, use the DELETE statement.

Example

Delete the employee data from the emp_date table in the previous example
without dropping the table.

(All three examples are valid syntax which perform the operation.)

DELETE FROM emp_data ALL;


DELETE FROM emp_data;

DELETE emp_data;

 Deletes all data in emp_data.


 Table definition remains in the Data Dictionary, so you can repopulate it.
 Access rights to the table remain unchanged.

ALTER TABLE

Once a table has been created, certain characteristics are not alterable, such as
the Primary Index choice. To change them you must CREATE a new table which
includes the new characteristics, then populate that table.

Other characteristics are alterable. You can use the ALTER TABLE statement to
modify these characteristics.

ALTER TABLE

1. ADDs and/or DROPs columns from an empty or populated table:


2.
3. ALTER TABLE emp_data
4. ADD educ_level CHAR(1), ADD insure_type SMALLINT
5. ;
6.
7. ALTER TABLE emp_data
8. DROP educ_level, DROP insure_type
9. Changes the attribute options on existing columns:

ALTER TABLE emp_data


ADD birthdate FORMAT 'mmmBdd,Byyy"
;

Note: In this example, the birthday column already exists. We are


adding FORMAT to the birthday column.

10. Makes a NO FALLBACK table into a FALLBACK table, or vice versa:

ALTER TABLE emp_data


,FALLBACK
;
11. Combines various changes to the table structure and protection:

ALTER TABLE emp_data


,NO FALLBACK
DROP insure_type
,ADD educ_level CHAR(1)
;

Note: Switching a table from FALLBACK to NO FALLBACK can be used to


reclaim database space when needed.

CREATE a Secondary Index

Indexes may be defined when creating a table with the CREATE TABLE
statement, or alternatively, they may be created after the fact using the CREATE
INDEX statement.

Primary indexes are always created at table creation time. Secondary indexes
may be created at table creation or after the fact.

The CREATE INDEX statement is used to create secondary indexes on an existing


table. Primary indexes must be created when you create the table and cannot be
changed without dropping and re-creating the table (and specifying a new
Primary Index).

Secondary indexes may be created with or without an identifying name.

Example

Create two secondary indexes on the employee table:

 A unique secondary index (USI) on employee name (named) .


 A non-unique secondary index (NUSI) on job code (unnamed).

USI (named)

CREATE UNIQUE INDEX fullname


(last_name, first_name)
ON emp_data;

Note: We know this is a USI because primary indexes can't be created (except
when the table is created). This index is named 'fullname'.

NUSI (unnamed)
CREATE INDEX
(job_code)
ON emp_data;

Note: Assigning names to indexes is optional. It has some advantages in terms


of simplifying the syntax used to identify the index in subsequent SQL
commands.

HELP INDEX

HELP INDEX <tablename> displays index definitions for the specified table. If the
index is unnamed, the "Index Name" will display as NULL. Naming indexes is
optional, however named indexes provide more ease of use in SQL commands
we shall see later.

Note: HELP INDEX may sometimes produce a very wide report. In this case, the
best way to view the output is to use the .SET FOLDLINE and .SET SIDETITLES
features of BTEQ.

What are the indexes on the emp_data table?

.SET FOLDLINE ON;


.SET SIDETITLES ON;

HELP INDEX emp_data;

Unique?: Y UPI on employee_number


Primary//or//Secondary?: P
Column Names: employee_number
Index Id: 1
Approximate Count: 0
Index Name: ?
Unique?: N NUSI on department_number
Primary//or//Secondary?: S
Column Name:s department_number
Index Id: 4
Approximate Count: 0
Index Name: ?

Y USI on
Unique?:
last_name,first_name combined
Primary//or//Secondary?: S
Column Names: last_name,first_name
Index Id: 8
Approximate Count: 0
fullname The name we gave
Index Name:
to the index

Unique?: N NUSI on job_code


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. The Primary index always has an Index ID of 1; Secondary
indices have Index IDs in multiples of 4.

DROP INDEX

If you are dropping a named index, you can specify the index by either the index
name or its column definition.

If you are dropping an unnamed index, you must specify the index by naming
the columns which are associated with it.

Example

Delete both secondary indexes from the employee table.

DROP INDEX FullName ON emp_data;

DROP INDEX (job_code)


ON emp_data;

Note: Only one secondary index may be dropped per DROP statement.

Lab
Try It! For this set of lab questions you will need information from
the Database Info document.

To start the online labs, click on the Telnet button in the lower
left hand screen of the course. Two windows will pop-up: a
BTEQ Instruction Screen and your Telnet Window. Sometimes
the BTEQ Instructions get hidden behind the Telnet Window.
You will need these instructions to log on to Teradata.

Hint: Prior to doing these labs, it will be helpful to reset


your default database to your own user id (i.e.
DATABASE tdxxx;).

Click on the buttons to the left to see the answers.

Answers: A. CREATE an employee table in your own database


Lab A identical to the employee table in the
Lab B Customer_Service database. Use the following
Lab C command to assist you in creating the new table in
Lab D your own database.
B. SHOW TABLE CUSTOMER_SERVICE.EMPLOYEE;

Note: This table is used in many subsequent labs.

C. Modify the emp_new table created in Lab A to:

Remove fallback protection.


Add a numeric column called 'salary_level' as a
BYTEINT.
Add a unique secondary index on the salary_level
column.

D. Do a HELP INDEX to display the indexes for your table.


E. If you have completed Labs B and C, ALTER the table
to reverse Lab B. (i.e., DROP the index; DROP the
column; Return table to FALLBACK)

13.) Data Manipulation

Objectives

After completing this module, you should be able to:


 Insert data rows into a table.
 Update existing rows in a table.
 Delete rows from a table.

Data Manipulation

Data Manipulation consists of four commands:

 INSERT
-Add a row to a table.
 INSERT SELECT
-Add rows to a table from another table.
 UPDATE
-Change column values in existing rows of a table.
 DELETE
-Remove rows from a table.

INSERT

INSERT allows you to add a new row to a table.

Example

There are two types of insert:

1) Insert a new employee into the employee table:

INSERT INTO employee


VALUES (1210, NULL, 401, 412101, 'Smith',
'James', 890303, 460421, 41000);

EMPLOYEE (Before Inserts)

MANAGER
EMPLOYEE DEPARTMENT JOB LAST FIRST HIRE BIRTH SALARY
EMPLOYEE
NUMBER NUMBER CODE NAME NAME DATE DATE AMOUNT
NUMBER

PK FK FK FK

1006 1019 301 312101 Stein John 761015 531015 2945000


1008 1019 301 312102 Kanieski Carol 770201 580517 2925000
1005 0801 403 431100 Ryan Loretta 761015 550910 3120000
1004 1003 401 412101 Johnson Darlene 761015 460423 3630000
1007 1005 403 432101 Villegas Arnando 770102 370131 4970000
1003 0801 401 411100 Trader James 760731 470619 3785000

2) Insert a new employee with only partial data:

INSERT INTO employee


(last_name, first_name, hire_date,
birthday, salary_amount, employee_number)
VALUES ('Garcia', 'Maria', 861027, 541110,
76500.00, 1291);

EMPLOYEE (After Inserts)

MANAGER
EMPLOYEE DEPARTMENT JOB LAST FIRST HIRE BIRTH SALARY
EMPLOYEE
NUMBER NUMBER CODE NAME NAME DATE DATE AMOUNT
NUMBER

PK FK FK FK

1006 1019 301 312101 Stein John 761015 531015 2945000


1008 1019 301 312102 Kanieski Carol 770201 580517 2925000
1005 0801 403 431100 Ryan Loretta 761015 550910 3120000
1004 1003 401 412101 Johnson Darlene 761015 460423 3630000
1007 1005 403 432101 Villegas Arnando 770102 370131 4970000
1003 0801 401 411100 Trader James 760731 470619 3785000
1210 401 412101 Smith James 890303 460421 4100000

1291 Garcia Maria 861027 541110 7650000

Note: Columns for which no values are inserted, will receive either their
assigned default value (as provided by the DEFAULT or WITH DEFAULT
options in the CREATE TABLE statement), or a NULL value if no default is
specified but nulls are allowed.

INSERT SELECT

Use INSERT SELECT to copy rows from one table to another.

The syntax is as follows:

INSERT INTO target_table SELECT * FROM source_table;

The SELECT portion of the statement may be used to define a subset of rows
and/or a subset of columns to be inserted to the target table.
Problem

To create a duplicate of the 'emp' table called 'emp_copy'.

Solution

First create the table 'emp_copy' with the same table definition as 'emp', then do
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 desired.

Problem

Create a table for tracking birthdays and populate it with data from the employee
table.

Solution

First, create a table which will contain the required rows and columns.

CREATE TABLE birthdays


(empno INTEGER NOT NULL
,lname CHAR(20) NOT NULL
,fname VARCHAR(30)
,birth DATE)
UNIQUE PRIMARY INDEX (empno);

Then, use INSERT SELECT to populate the new table. Only the required columns are
selected for insertion. All rows are included.

INSERT INTO birthdays


SELECT employee_number
,last_name
,first_name
,birthdate
FROM employee;

BIRTHDAYS

BIRTH
EMPNO LNAME FNAME
DATE
PK
1006 Stein John 531015
1008 Kanieski Carol 580517
1005 Ryan Loretta 550910
1004 Johnson Darlene 460423
1007 Villegas Arnando 370131
1003 Trader James 470619

EMPLOYEE

MANAGER
EMPLOYEE DEPARTMENT JOB LAST FIRST HIRE BIRTH SALARY
EMPLOYEE
NUMBER NUMBER CODE NAME NAME DATE DATE AMOUNT
NUMBER

PK FK FK FK

1006 1019 301 312101 Stein John 761015 531015 2945000


1008 1019 301 312102 Kanieski Carol 770201 580517 2925000
1005 0801 403 431100 Ryan Loretta 761015 550910 3120000
1004 1003 401 412101 Johnson Darlene 761015 460423 3630000
1007 1005 403 432101 Villegas Arnando 770102 370131 4970000
1003 0801 401 411100 Trader James 760731 470619 3785000

Note: .

In the Advanced Teradata SQL course we will see a feature of SQL which
permits the CREATE TABLE statement and the INSERT SELECT statement to be
combined into a single statement called CREATE TABLE WITH DATA.

UPDATE

UPDATE allows you to modify one or many columns of one or many rows in a
single table.
The WHERE condition can include:

 Columns from the table being updated.


 Joins with columns from other tables.
 Subqueries.

EMPLOYEE (Before modification)

MANAGER
EMPLOYEE DEPARTMENT JOB LAST FIRST HIRE BIRTH SALARY
EMPLOYEE
NUMBER NUMBER CODE NAME NAME DATE DATE AMOUNT
NUMBER

PK FK FK FK

1006 1019 301 312101 Stein John 761015 531015 2945000


1008 1019 301 312102 Kanieski Carol 770201 580517 2925000
1005 0801 403 431100 Ryan Loretta 761015 550910 3120000
1004 1003 401 412101 Johnson Darlene 761015 460423 3630000
1007 1005 403 432101 Villegas Arnando 770102 370131 4970000
1003 0801 401 411100 Trader James 760731 470619 3785000
1010 1003 401 412101 Rogers Frank 770301 350423 4600000

Problem

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

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

EMPLOYEE (After)

MANAGER
EMPLOYEE DEPARTMENT JOB LAST FIRST HIRE BIRTH SALARY
EMPLOYEE
NUMBER NUMBER CODE NAME NAME DATE DATE AMOUNT
NUMBER

PK FK FK FK

1006 1019 301 312101 Stein John 761015 531015 2945000


1008 1019 301 312102 Kanieski Carol 770201 580517 2925000
1005 0801 403 431100 Ryan Loretta 761015 550910 3120000
1004 1003 401 412101 Johnson Darlene 761015 460423 3630000
1007 1005 403 432101 Villegas Arnando 770102 370131 4970000
1003 0801 401 411100 Trader James 760731 470619 3785000

1010 1005 403 432101 Rogers Frank 770301 350423 4600000

UPDATE Using Subqueries or Joins

Problem

Update the employee table to give everyone in all support departments a 10%
raise. Department numbers for all of the support departments are not known.

DEPARTMENT

MANAGER
DEPARTMENT DEPARTMENT BUDGET
EMPLOYEE
NUMBER NAME AMOUNT
NUMBER

PK FK

501 marketing sales 8005000 1017


301 research and development 46560000 1019
302 product planning 22600000 1016
403 education 93200000 1005

402 software support 30800000 1011

401 customer support 98230000 1003


201 technical operations 29380000 1025

EMPLOYEE

MANAGER
EMPLOYEE DEPARTMENT JOB LAST FIRST HIRE BIRTH SALARY
EMPLOYEE
NUMBER NUMBER CODE NAME NAME DATE DATE AMOUNT
NUMBER

PK FK FK FK

1006 1019 301 312101 Stein John 761015 531015 2945000


1008 1019 301 312102 Kanieski Carol 770201 580517 2925000
1005 0801 403 431100 Ryan Loretta 761015 550910 3120000

1004 1003 401 412101 Johnson Darlene 761015 460423 3993000


1007 1005 403 432101 Villegas Arnando 770102 370131 4970000

1003 0801 401 411100 Trader James 760731 470619 4163500

Solution 1

Using Subquery:
UPDATE employee
SET salary_amount=salary_amount * 1.10
WHERE department_number IN
(SELECT department_number
FROM department
WHERE department_name LIKE '%Support%')
;

Solution 2

Using Join:

UPDATE employee
SET salary_amount=salary_amount * 1.10
WHERE employee.department_number =
department.department_number
AND department_name LIKE '%Support%'
;

Note: In an update, you can't use the ON clause, so the join condition is specified
in the WHERE clause.

DELETE

DELETE allows you to delete rows from a single table. If no WHERE clause is
specified, then all rows are deleted.

The WHERE condition can reference:

 Column values in the target table.


 Column values based on a subquery against another table.
 Column values based on a join with another table.

Problem

Remove all employees in department 301 from the employee table.

EMPLOYEE
MANAGER
EMPLOYEE DEPARTMENT JOB LAST FIRST HIRE BIRTH SALARY
EMPLOYEE
NUMBER NUMBER CODE NAME NAME DATE DATE AMOUNT
NUMBER

PK FK FK FK

1006 1019 301 312101 Stein John 761015 531015 2945000

1008 1019 301 312102 Kanieski Carol 770201 580517 2925000


1005 0801 403 431100 Ryan Loretta 761015 550910 3120000
1004 1003 401 412101 Johnson Darlene 761015 460423 3630000
1007 1005 403 432101 Villegas Arnando 770102 370131 4970000
1003 0801 401 411100 Trader James 760731 470619 3785000
1010 1005 403 432101 Rogers Frank 770301 350423 4600000

Solution

DELETE FROM employee


WHERE department_number = 301;

Problem

Delete ALL data in the employee table.

EMPLOYEE

MANAGER
EMPLOYEE DEPARTMENT JOB LAST FIRST HIRE BIRTH SALARY
EMPLOYEE
NUMBER NUMBER CODE NAME NAME DATE DATE AMOUNT
NUMBER

PK FK FK FK

1005 0801 403 431100 Ryan Loretta 761015 550910 3120000


1004 1003 401 412101 Johnson Darlene 761015 460423 3630000
1007 1005 403 432101 Villegas Arnando 770102 370131 4970000
1003 0801 401 411100 Trader James 760731 470619 3785000
1010 1003 403 432101 Rogers Frank 770301 350423 4600000

Solution

DELETE FROM employee ALL; /* Teradata syntax */

DELETE FROM employee; /* ANSI standard syntax */

Both produce the same result.


DELETE Using Subqueries or Joins

Problem

Remove all employees assigned to a temporary department for which the


department name is "Temp".

EMPLOYEE

MANAGER
EMPLOYEE DEPARTMENT JOB LAST FIRST HIRE BIRTH SALARY
EMPLOYEE
NUMBER NUMBER CODE NAME NAME DATE DATE AMOUNT
NUMBER

PK FK FK FK

1006 1019 301 312101 Stein John 761015 531015 2945000


1008 1019 301 312102 Kanieski Carol 770201 580517 2925000
1005 0801 403 431100 Ryan Loretta 761015 550910 3120000
1004 1003 401 412101 Johnson Darlene 761015 460423 3630000
1007 1005 403 432101 Villegas Arnando 770102 370131 4970000
1003 0801 401 411100 Trader James 760731 470619 3785000

DEPARTMENT

MANAGER
DEPARTMENT DEPARTMENT BUDGET
EMPLOYEE
NUMBER NAME AMOUNT
NUMBER

PK FK

501 marketing sales 8005000 1017


301 research and development 46560000 1019
302 product planning 22600000 1016
403 education 93200000 1005
402 software support 30800000 1011
401 customer support 29230000 1003
600 Temp 1099

Solution 1

Using Subquery:

DELETE FROM employee


WHERE department_number IN
(SELECT department_number
FROM department
WHERE department_name ='Temp');
Solution 2

Using Join:

DELETE FROM employee


WHERE employee.department_number=department.department_number
AND
department.department_name='Temp';

Note: In either case, no rows are removed from the 'employee' table because no
current employees are assigned to the 'Temp' department.

Lab

Try It! For this set of lab questions you will need information from
the Database Info document.

To start the online labs, click on the Telnet button in the lower
left hand screen of the course. Two windows will pop-up: a
BTEQ Instruction Screen and your Telnet Window. Sometimes
the BTEQ Instructions get hidden behind the Telnet Window.
You will need these instructions to log on to Teradata.

Hint: Prior to doing these labs, it will be helpful to reset


your default database to your own user id (i.e. DATABASE
tdxxx;).

Click on the buttons to the left to see the answers.

The following labs are interdependent. Be sure to do them in


sequence.

Answers: A. Use an INSERT SELECT statement to copy all rows from


Lab A the Customer_Service employee table into the
Lab B emp_new table created in the previous module.
Lab C B. Write SQL code to accomplish the following:

Select all department 301 employees to include


employee number, last name, job code, and salary
from the table created in Lab A in the preceding Data
Definition module.

1. Note salary amounts.


2. Update your emp_new table to give a 15% raise
to all employees in department 301.
3. Verify results.

C. Reverse the effects of the update in exercise B. Verify


the reversal.

14.) Simple Macros

Objectives

After completing this module, you should be able to:

 CREATE and EXEC a simple macro.


 REPLACE a macro.
 DROP a macro.

Overview of Macros

A macro is a Teradata extension to ANSI SQL that contains prewritten SQL


statements. The actual text of the macro is stored in a global repository called
the Data Dictionary (DD). Macros are database objects and thus they belong to a
specified user or database. They may contain one or more SQL statements.
Macros have special efficiencies in the Teradata environment and are highly
desirable for building reusable queries.

A macro allows you to name a set of one or more statements. When you need
to execute those statements, simply execute the named macro. Macros provide a
convenient shortcut for executing groups of frequently-run SQL statements.

The following table is a fairly complete list of commands you may use to
manipulate macros.

CREATE MACRO macroname AS ( Define a macro and store it in the DD.


. . . );
EXEC macroname; Execute statements within a macro.
SHOW MACRO macroname; Display a macro.
REPLACE MACRO macroname AS Apply changes to a macro or create a
(. . . ); new one.
DROP MACRO macroname; Remove a macro definition from the
DD.
EXPLAIN EXEC macroname; Display EXPLAIN text for the macro's
execution.

CREATE MACRO

The CREATE MACRO command allows you to define a set of SQL statements and
put them into an executable statement.

Example

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

Notice that there is a semicolon before the closing parenthesis. This is a required
element of macro syntax. The CREATE MACRO statement will fail if there is a
syntax error anywhere in the body of the SQL statement. If a macro exists, it is
guaranteed to have previously been syntax checked. This does not guarantee
that it will work without errors because objects referenced within the macro
(e.g., the employee table) may not exist any longer or may have changed.

EXECUTE Macro

To execute a macro, simply precede its name with the EXEC command.

EXEC birthday_list;
last_name first_name birthdate
----------- ----------- ---------------
Morrissey Jim 43/04/29
Short Michael 47/07/07

DROP Macro

Use the DROP MACRO command to delete a macro.

DROP MACRO birthday_list;

This command removes the macro from the containing database and also
removes its entry from the Data Dictionary.

REPLACE Macro

You need to resubmit the entire contents of amacro to modify it. It is convenient
to display current macro contents so you can cut and paste them into a text
editor. You may then modify the macro without retyping the entire command. To
display the definition of a macro, use the SHOW command as seen here:

SHOW MACRO birthday_list;

Result

CREATE MACRO birthday_list AS


SELECT last_name
,first_name
,birthdate
FROM employee
WHERE department_number = 201
ORDER BY birthdate;) ;

In editing the macro, change the CREATE command to the REPLACE command,
and make the appropriate changes, such as adding a minor sort to the ORDER BY
clause. Comments may optionally be added.

REPLACE MACRO birthday_list AS


/* Macro is being updated for sorting sequence */
(SELECT last_name
,first_name
,birthdate
FROM employee
WHERE department_number = 201
ORDER BY birthdate, last_name;);
Submit this as a BTEQ script. The old birthday_list macro will be replaced by the
new one.

Lab

Try It! For this set of lab questions you will need information from the
Database Info document.

To start the online labs, click on the Telnet button in the lower
left hand screen of the course. Two windows will pop-up: a
BTEQ Instruction Screen and your Telnet Window.

Sometimes the BTEQ Instructions get hidden behind the Telnet


Window. You will need these instructions to log on to Teradata.

Be sure to change your default database to the


Customer_Service database in order to run these labs.

Click on the buttons to the left to see the answers.

References to 'tdxxx' are to be substituted with your personal


userid.

Name MACROs to match the LAB numbers. For example, give


the macro for the first lab below the name Lab 7_A.

Answers: A. Write a simple macro to create a customer geographical


Lab A distribution list from the location table. Include location
Lab B number, customer number, city and state (limit city and
Lab C state to 14 characters each). Sort by city within state.
Lab D CREATE the macro. Execute the macro. (The CREATE and
EXEC should be separate scripts.)
Lab E

Note: CUSTOMER_SERVICE is a Read-Only database. You


need to create the macros in your own user space. Tell
the system to do this either by:

1. DATABASE tdxxx; CREATE MACRO LAB 7_A


AS...

or
2. CREATE MACRO tdxxx.Lab 7_A as...

Note: This lab is used again for Lab B and Lab D.

B. Modify the macro from Lab A to take location number


out. Add zip code as the last column on the report. Zip
code should be the lowest level of sort. Limit your
selection to customers based in the state of Illinois.
Save the modified macro under a new name. Submit
and execute the new macro.
C. Use the appropriate HELP command to find the names
of all macros in your database.
D. Replace the macro you created for Lab A, with these
changes: Select only those customers in the city of
Chicago; Include their first address line as the last
column of the report; Remove the state from the report;
Sort the output by customer number in descending
order.
E. Drop your Lab 7_A macro.

15.) Parameterized Macros

Objectives

After completing this module, you should be able to:

 Create and execute a parameterized macro.

Macros Revisited

Macros contain one or more prewritten SQL statements that are stored in the
Teradata Data Dictionary. They can be executed from any viable SQL front-end,
including:

 Teradata SQL Assistant


 BTEQ
 Preprocessor
 CLI
 LOGON Startup
 Another macro.
Other key points to note about Macros:

 Macros are a Teradata extension to SQL.


 Macros can only be executed with the EXEC privilege.
 Macros can provide column level security.

Note: If a user has EXEC privileges he may execute the macro. It doesn't matter
whether or not he has privileges for the underlying tables or views that the
macro uses.

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;
);

In parentheses following the macro name is the parameter list. It names each
parameter followed by its data type. When a parameter is used in the body of a
macro, it is always preceded by a colon.

Employee Table:

Manager
Employee Employee Department Job Last First
Number Number Number Code Name Name
1008 1019 301 312102 Kanieski Carol
1010 1003 401 412101 Rogers Frank
1014 1011 402 422101 Crane Robert
1006 1019 301 312101 Stein John
1017 801 501 511100 Runyon Irene
1003 801 401 411100 Trader James
1019 801 301 311100 Kubic Ron
1011 801 402 421100 Daly James
1013 1003 401 412102 Phillips Charles
1009 1005 403 432101 Lombardo Domingus
1025 801 201 211100 Short Michael
1024 1005 403 432101 Brown Allen
1007 1005 403 432101 Villegas Arnando
1005 801 403 431100 Ryan Loretta
1021 1025 201 222101 Morrissey Jim
1020 1005 403 432101 Charles John
1022 1003 401 412102 Machado Albert
801 801 100 111100 Trainer I.B.
1015 1017 501 512101 Wilson Edward
1002 1003 401 413201 Brown Alan
1004 1003 401 412101 Johnson Darlene
1016 801 302 321100 Rogers Nora
1018 1017 501 512101 Ratzlaff Larry
1001 1003 401 412101 Hoover William
1023 1017 501 512101 Rabbit Peter
1012 1005 403 432101 Hopkins Paulene

To Execute

EXEC dept_list (301);

Result

last_name
------------
Stein
Kanieski
Kubic

Macros with Multiple Parameters

Macros may have more than one parameter. Each name and its associated type
are separated by a comma from the next name and its associated type. The
order is important. The first value in the EXEC of the macro will be associated
with the first value in the parameter list. The second value in the EXEC is
associated with the second value in the parameter list, and so on.

Example

Create the macro:

CREATE MACRO emp_check (dept INTEGER


,sal_amt DEC(9,2))
AS
(SELECT employee_number from employee
WHERE department_number = :dept
AND salary_amount < :sal_amt;)
;

Execute the macro:

EXEC emp_check (301, 50000);

Results:

employee_number
-------------------
1006
1008

In this example, 301 is associated with the department number and 50000 is
associated with the salary amount.

Using a 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;
);

EXECUTE the INSERT MACRO (With Positional Parameter Values):

 The macro consists of an INSERT statement followed by a SELECT.


 The SELECT simply reads the row just inserted.
 Input data must be in the order specified in the Macro parameter list.
 Input data must match the exact number of parameters specified in the
list.
 Use the keyword NULL to explicitly pass a null to the macro.
 Use positional commas to implicitly pass a null, or a specified default
value.

EXEC new_dept (505 ,610000.00 , 'Marketing Research', 1007);


Number Name Budget Manager
-------- --------------- -------- ----------
Marketing
505 610000.00 1007
Research

EXEC new_dept (102 , , 'Payroll', NULL);


Number Name Budget Manager
-------- --------------- -------- ----------
102 Payroll .00 ?

In the example above, the value after 102 has been omitted, hence the two
commas in a row. In such cases the parameter value will be set to the default
specified for in the CREATE MACRO statement. In this case it is 0.

Note, for this example to work, both the budget and manager columns must
allow nulls or have a default value in the department table definition.

EXECUTE the INSERT MACRO

Another option available for passing parameters to a macro is to explicitly name


the parameters with an associated value as seen in this example. When this
approach is selected, the parameters may be specified in any sequence. Note in
the following example, implicitly defaulted parameters (like 'mgr') may simply be
omitted without accounting for their position.
Example

EXEC new_dept ( name = 'accounting'


,budget = 425000.00
,dept = 106 )
;
Number Name Budget Manager
------- ------- -------- ----------
106 accounting 425000.00 ?

Performance Note: Parameterized macros may be submitted multiple times


with different parameter values each time. Because the body of the query
doesn't change, it permits execution of the same optimized 'steps' which are
cached for re-use. This feature of macros makes them highly desirable from a
performance standpoint.

Lab

Try It! For this set of lab questions you will need information from the
Database Info document.

To start the online labs, click on the Telnet button in the lower left
hand screen of the course. Two windows will pop-up: a BTEQ
Instruction Screen and your Telnet Window.

Sometimes the BTEQ Instructions get hidden behind the Telnet


Window. You will need these instructions to log on to Teradata.
Hint: Prior to doing these labs, it will be helpful to reset your
default database to your own user id (i.e. DATABASE tdxxx;).

Click on the buttons to the left to see the answers.

To do the following labs, you will first need to create and populate your
own copy of the department table. This may be accomplished by
executing the following commands:

DATABASE tdxxx;

CREATE TABLE dept_new, FALLBACK


(department_number SMALLINT
,department_name CHAR(30) NOT NULL
,budget_amount DECIMAL(10,2)
,manager_employee_number INTEGER
)
UNIQUE PRIMARY INDEX (department_number)
,UNIQUE INDEX (department_name);

INSERT INTO dept_new SELECT *


FROM Customer_Service.department;

Answer A. Create a parameterized MACRO to insert a new row into your


s: dept_new table. Display the newly inserted row for verification.
Lab Insert three rows into the table using the MACRO. Use the values
A below for the columns shown:
Lab
B department_num department_n __budg manager_em
Lab ber ame et pno
C 601 shipping 800,000 ?
Lab 1,200,0
701 credit 1018
D 00
president’s 5,000,0
905 801
staff 00

B. Note: Remember to override your default database.


C. Execute the exercise A macro again. Put EXPLAIN in front of
the EXECute to see what the Teradata RDBMS is doing.
D. Write a parameterized MACRO to first select, then update your
employee table to give all employees in a given department a
flat salary increase. Actual department number and salary
increase will be given at execution time. The select should
precede the update and should include employee number, last
name, and two salary columns: one titled “Current Salary”, and
the other titled “New Salary”. Format the salary columns with
floating dollar signs. Limit last name to 10 characters, and sort
by last name. Execute this MACRO to give department 401
employees a $1000 raise. Execute it again to reverse the
effects of the previous run.
E. Write a parameterized MACRO to create a report showing the
last name, department and salary for employees within a salary
range that will be supplied at run time. Execute the MACRO to
find all employees in the over $50,000 under $100,000 income
bracket. Execute it again to find all employees in the under
$30,000 income bracket.

16.) Aggregating Groups

Objectives

After completing this module, you should be able to:

 Aggregate column data using the aggregate functions SUM, COUNT,


AVERAGE, MINIMUM, MAXIMUM.
 Use the GROUP BY clause to aggregate over defined groups.

Aggregate Operators

Aggregate operators perform computations on values in a specified group. The


five aggregate operators are:

ANSI Standard Teradata Supported


COUNT COUNT
SUM SUM
AVG AVERAGE, AVG
MAX MAXIMUM, MAX
MIN MINIMUM, MIN

AGGREGATE operations ignore NULLs and produce ONLY single-line answers.

Example

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 ;

Result

COUNT SUM SALARY AVG SALARY MAX SALARY MIN SALARY


6 213750.00 35625.00 49700.00 29250.00

Note: If one salary amount value had been NULL, the COUNT would have
returned a count of 5. In that case, the average would have reflected an average
of only five salaries. To COUNT all table rows use COUNT (*), which will count rows
regardless of the presence of NULLs.

Why Aggregation is Useful

Suppose we would like to find the total amount of money spent by each
department on employee salaries. Without the GROUP BY clause, we could
attempt to get an answer by running a separate query against each department.

Solution

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
Question: What if there are 1000 departments?

GROUP BY provides the answer with a single query, regardless of how many
departments there are.

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

Hint: Think of GROUP BY as For Each.

GROUP BY and the WHERE Clause

The WHERE clause eliminates some rows before GROUP BY puts them into desired
groupings.

Problem

Compute total salaries by department for departments 401 and 403.

Solution
SELECT department_number
,SUM (salary_amount)
FROM employee
WHERE department_number IN (401, 403)
GROUP BY department_number
;
Sum
department_number
(salary_amount)
----------------------
-----------------------
403 80900.00
401 74150.00

GROUP BY and ORDER BY

GROUP BY does not imply any ordering of the output. An ORDER BY clause is
needed to control the order of the ouput.

Problem

For departments 301, 401 and 403, find the total number of employees in each
department as well as the highest, lowest and average salaries for each
department. Order 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
WHERE department_number IN (301,401,403)
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.00 31,000.00 38,833.33
GROUP BY on Multiple Columns

It is possible and often desireable to GROUP BY more than one column. This
permits the query to compute aggregates of groups within groups. In the
following example, we are looking for salaries by job code (one group) within
department (second group).

By job code, what are the total salaries for departments 401 and 403?

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

2 Rules of Aggregations:

1. Whenever both aggregate and non-aggregate columns are selected, a


GROUP BY clause is required.
2. All non-aggregated selected columns must be included in the GROUP BY
clause.

Note: Repeating values such as '401' above may be suppressed using the BTEQ
command:

.SET SUPPRESS ON 1; /* Suppress repeating values


on first column */

This will cause the value to be displayed only the first time.

The resulting report would look as follows:


department_number job_code SUM (salary_amount)
--------------------- ---------- -----------------------
401 411100 37850.00
412101 107825.00
412102 56800.00
413201 43100.00
403 431100 31200.00
432101 201800.00

GROUP BY and HAVING Condition

HAVING is just like WHERE , except that it applies to groups rather than rows.
HAVING qualifies and selects only those groups that satisfy a conditional
expression.

Problem

Determine which departments have average salaries of less than $36,000.


Generate the report using the HAVING clause:

SELECT department_number AS DEPT


COUNT (*) AS #_EMPS
,CAST ( SUM (salary_amount) AS FORMAT 'zz,zzz,zz9.99')
AS TOTAL
,CAST ( MAX (salary_amount) AS FORMAT 'zz,zzz,zz9.99')
AS HIGHEST
,CAST ( MIN (salary_amount) AS FORMAT 'zz,zzz,zz9.99')
AS LOWEST
,CAST ( AVG (salary_amount) AS FORMAT 'zz,zzz,zz9.99')
AS MEAN
FROM employee
GROUP BY department_number
HAVING AVG (salary_amount) < 36000
;
Since only one department (401) has an average salary less than $36,000, the
result is a single row, as follows:

DEPT #_EMPS TOTAL HIGHEST LOWEST AVERAGE


401 3 245,575.00 46,000.00 24,500.00 35,082.14
GROUP BY Summary

Here is the order of evaluation within a SQL statement if all four clauses are
present:

WHERE

 Eliminates some or all rows immediately based on condition.


 Only rows which satisfy a WHERE condition are eligible for inclusion in
groups.

GROUP BY

 Puts qualified rows into desired groupings.

HAVING

 Eliminates some (or all) of the groupings based on condition.

ORDER BY

 Sorts final groups for output.

(ORDER BY is not implied by GROUP BY)

Lab

Try It! For this set of lab questions, you will need information from
the Database Info document.

To start the online labs, click on the Telnet button in the


lower left hand screen of the course. Two windows will pop-
up: a BTEQ Instruction Screen and your Telnet Window.

Sometimes the BTEQ Instructions get hidden behind the


Telnet Window. You will need these instructions to log on to
Teradata.

Be sure to change your default database to the


Customer_Service database in order to run these labs.

Click on the buttons to the left to see the answers.

Answers: A. Management needs to know the impact of salary


Lab A increases if all employees in every department
Lab B receive a ten percent salary increase. Create a report
showing minimum and maximum salaries for each
department. Format the report as shown below. Limit
department name to 9 characters. Format dollar
columns with zero-suppress and commas. Sort by
department.
B.
C. Dept Dept Minimum Maximum
Current Adjusted
D. Nbr Name Salary Salary
Salary Salary
E. --------- --------- ---------- -------
--- -------- ---------
F. Management needs a summary report showing all
departments, jobs within departments, the number of
employees doing each job, and the average salary for
each job category. Sequence the report by
department and job code within department. Let the
column titles default.

17.) Totals and Subtotals

Objectives

After completing this module, you should be able to:

 Create subtotals using WITH....BY.


 Create final totals using WITH.
 Eliminate duplicate results using the DISTINCT option.

Using WITH...BY for Subtotals

The WITH...BY clause is a Teradata extension that creates subtotal lines for a
detailed list. It differs from GROUP BY in that detail lines are not eliminated.

The WITH...BY clause allows subtotal "breaks" on more than one column and
generates an automatic sort on all "BY" columns.

Creating a Report Using WITH..BY


Problem

To display employee name and salary with subtotals by department.

Solution

SELECT last_name AS NAME


,salary_amount AS SALARY
,department_number AS DEPT
FROM employee
WITH SUM(salary) BY DEPT
;

Note: The "BY DEPT" phrase causes an automatic sort on the Dept column.

Result

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

Note: "WITH BY" is a non-ANSI Teradata extension. It is supported by BTEQ,


but not supported by ODBC clients.

WITH..BY Multiple Aggregates

Multiple aggregates within the same WITH BY clause are possible if all aggregates
are based on the same 'break' column. In the following example, both
aggregates are generated by department. Note that while WITH BY produces
aggregates similar to the GROUP BY functionality, the difference is that GROUP BY
does not show the detail rows upon which the aggregates are based.
Problem

Show salary subtotals and averages by department and also show the individual
employee salaries.

Solution

SELECT last_name AS NAME


,salary_amount AS SALARY
,department_number AS DEPT
FROM employee
WHERE employee_number
BETWEEN 1003 AND 1008
WITH SUM(salary)(TITLE 'Dept Total')
,AVG(salary)(TITLE 'Dept Avg ')BY DEPT
;

Result

NAME SALARY DEPT

Stein 29450.00 301


Kaniesk 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
Note: The BY DEPT clause causes results to be sorted by department.

WITH... BY Multiple Subtotal Levels

You may use several "WITH BY" clauses together in an SQL statement.

The order in which you specify them determines the order of the sorted output.

Problem

Show total salaries by department and by job code within department for
departments 401 and 501. Also show the detail salary for each employee.

Solution

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
;

Result

Dept Job Empl Sal


-------- ------------ -------- --------------
401 411100 1003 37850.00
------------
JOB TOTAL 37850.00

401 412101 1010 25525.00


401 412101 1004 36300.00
401 412101 1010 46000.00
------------
JOB TOTAL 107825.00

401 412102 1022 32300.00


401 412102 1013 24500.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 1018 54000.00


501 512101 1023 26500.00
501 512101 1015 53625.00
------------
JOB TOTAL 134125.00

------------
DEPT TOTAL 200125.00

Note: Because there are two BY clauses in this query, their sequence in the
query affects how the final report is sorted. Because 'BY Dept' is the last one
specified, it becomes the highest level sort column, thus the report is sorted as
job code within department.

Creating Final Totals Using WITH

The WITH clause without 'BY' is used to create a grand totals.

Problem

Display employee numbers and salary amounts for department 301 and a final
total for the department.

Solution

SELECT employee_number
,salary_amount
FROM employee
WHERE department_number = 301
WITH SUM(salary_amount)(TITLE 'GRAND TOTAL')
ORDER BY employee_number
;

Result

employee_number salary_amount
------------------------ --------------------
1006 29450.00
1008 29250.00
1019 57700.00
------------
GRAND TOTAL 116400.00

WITH is a non-ANSI Teradata extension and is not supported by ODBC clients.

DISTINCT Modifier

The DISTINCT modifier is used in conjuction with the COUNT aggregate to prevent
the same value from being counted more than once.

Problem

Count the number of managers for employees numbered between 1003 and
1008.

Solution

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')
;

Result

employee_number department_number manager


--------------- ----------------- -----------
1003 401 801
1007 403 1005
1004 401 1003
1008 301 1019
1005 403 801
1006 301 1019
-----------
TOTAL MANAGERS 6

Note that even though the count is represented as six, there are really only four
managers.

To solve this problem, use the DISTINCT modifier.

Solution

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')
;

Result

employee_number department_number manager


--------------- ----------------- -----------
1003 401 801
1004 401 1003
1007 403 1005
1008 301 1019
1005 403 801
1006 301 1019
-----------
TOTAL MANAGERS 4

This gives you an actual count for the number of managers.

Note: When using DISTINCT with an aggregate function only a single column or
expression may be used.

Legal Example:

SELECT COUNT(DISTINCT(job_code))
,COUNT(DISTINCT(employee_number)).....
Illegal Example:

SELECT COUNT(DISTINCT(job_code, employee_number)).......

Combining WITH and WITH BY

WITH and WITH BY may be combined within the same query.

Problem

Show the salary for each employee with subtotals by department, a final total,
and results sorted by employee name.

Solution

SELECT last_name AS NAME


,salary_amount AS SALARY
,department_number AS DEPT
FROM employee
WHERE employee_number
BETWEEN 1003 and 1008
WITH SUM (SALARY) BY DEPT
WITH SUM (SALARY) (TITLE 'GRAND TOTAL')
ORDER BY NAME
;

Results

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

Note that the WITH BY clause controls the high level sort by department. The
ORDER BY clause is applied as a minor level sort, producing a sorted list of names
within sorted departments.

Final Totals Using WITH and GROUP BY

WITH and GROUP BY clauses may both appear in the same query. The GROUP BY
clause is needed when both aggregates and non-aggregates are in the SELECTed
columns. The WITH clause is needed when a final aggregation of all the groups is
desired.

Problem

Show the total and average salaries for each department plus a final total and
average for the company.

Solution

SELECT department_number (TITLE 'dept_no')


,SUM (salary_amount)
,AVG (salary_amount)
FROM employee
GROUP BY department_number
WITH SUM (salary_amount) (TITLE 'GRAND TOTAL')
,AVG (salary_amount) (TITLE ' ')
ORDER BY department_number
;

Result

dept_no SUM(salary_amount) AVG(salary_amount)


------------ ----------------------------- ----------------------------
301 58700.00 29350.00
401 74150.00 37075.00
403 80900.00 40450.00
----------------------------- ----------------------------
GRAND TOTAL 213750.00 35635.00

Summary of WITH...BY and WITH


The WITH...BY clause specifies summary lines and breaks, or grouping
conditions, that determine how results are returned. This clause is typically used
when you need to produce subtotals and also wish to see the detail rows.

WITH summarylist BY breaklist ASC/DESC:

 Will provide subtotals, subcounts, and subaverages, and also show detail
rows.
 Summarylist can specify more than one column.
 Breaklist can specify more than one column.
 Implied ORDER BY on the breaklist columns.
 WITH...BY determines the major sort key(s).
 ORDER BY specifies any additional minor sorts.
 An SQL statement can have several WITH...BY clauses.
 The highest level of sort is the last specified WITH...BY clause.
 Is not supported by ANSI standard or ODBC clients.

WITH summarylist:

The WITH clause produces grand total results for the entire answer set. This
clause is typically used when you need to produce final totals and also wish to
see the detail rows.

 Will provide a final or grand total, count or average.


 Summarylist may specify more than one column.
 Only a single WITH is allowed in a query.
 WITH must follow any WITH...BY syntax.
 Not supported by ANSI standard or ODBC clients.

Lab

Try It! For this set of lab questions you will need information from
the Database Info document.

To start the online labs, click on the Telnet button in the lower
left hand screen of the course. Two windows will pop-up: a
BTEQ Instruction Screen and your Telnet Window.

Sometimes the BTEQ Instructions get hidden behind the


Telnet Window. You will need these instructions to log on to
Teradata.
Be sure to change your default database to the
Customer_Service database in order to run these labs.

Click on the buttons to the left to see the answers.

Answers: A. Use the location table to find the customers located in


Lab A California.
Lab B Matching on customer number, list customer name,
number, and sales representatives
number from the customer table. Sort by sales
representatives number.
Give a count of customers at the end of the report as
shown below.

(Note, these labs will not work properly with an


ODBC client such as SQL Assistant. WITH and WITH BY
are not ODBC compliant clauses and thus are ignored
by ODBC clients.)

customer_name customer_number sales_employee_number


. . .
. . .
. . .
---------------
Total Cust X

A. Do a salary study report for departments 401 and 403,


excluding job codes 411100, 413201 and 431100. List
employee's last and first name (10 characters each),
department, job code and salary. Give totals for each
department and job code within department. Give a
grand total for salary. Give an average figure as well.
Sort by last name within department and job. Format
the report as follows:
B. last_name first_name Dept Job Salary
C. ------------ ------------ ---- ------ ---------
D. xxxxxxxxxx xxxxxxxxxx xxxx xxxxxx xxxxx.xx
E. xxxxxxxxxx xxxxxxxxxx xxxx xxxxxx xxxxx.xx
F. Job
Total xxxxx.xx
G. --------
H. Job Avg
xxxxx.xx
I. xxxxxxxxxx xxxxxxxxxx xxxx xxxxxx xxxxx.xx
J. xxxxxxxxxx xxxxxxxxxx xxxx xxxxxx xxxxx.xx
K. Job
Total xxxxx.xx
L. --------
M. Job Avg
xxxxx.xx
N. Dept
Total xxxxx.xx
O. --------
P. Dept
Avg xxxxx.xx
Q. xxxxxxxxxx xxxxxxxxxx xxxx xxxxxx xxxxx.xx
R. xxxxxxxxxx xxxxxxxxxx xxxx xxxxxx xxxxx.xx
S. Job
Total xxxxx.xx
T. --------
U. Job Avg
xxxxx.xx
V. Dept
Total xxxxx.xx
W. --------
X. Dept
Avg xxxxx.xx
Y. Grand
Total xxxxx.xx
Z. Grand
Avg xxxxx.xx

18.) Rankings, Samplings and Built-in Functions

Objectives

After completing this module, you should be able to:

 Perform simple rankings on rows in a table.


 Extract samples of data from a table
 Employ the Teradata built-in system functions.
 Retrieve the top n rows of an output result.

Simple Rankings

The RANK function permits a column to be ranked, either based on high or low
order, against other rows in the answer set. You may specify the order of
ranking by use of the ORDER BY clause within the RANK function. Descending
order will provide traditional ranking wherein the largest value is assigned a rank
of one. Ascending order will associate the largest value with the highest rank
value (i.e., typically a value > 1).

Most of the examples we will see are rankings of sales figures, where the larger
the amount, the better (i.e. lower number) the ranking.

The syntax for the RANK function is:

RANK( ) OVER (ORDER BY sales DESC)

where 'sales' ' represents the column to be ranked and the descending sort key
of the result.

Problem

Show the ranking of product sales for store 1001.

Solution

SELECT storeid
,prodid
,sales
,RANK( ) OVER (ORDER BY sales DESC) AS "Rank"
FROM salestbl
WHERE storeid = 1001;

Result

storeid prodid sales Rank


----------- ------ ----------- -----------
1001 F 150000.00 1
1001 A 100000.00 2
1001 C 60000.00 3
1001 D 35000.00 4

Things To Notice:

 WHERE clause qualifies rows to be ranked.


 When the order of sales is DESC, the highest sales amount is rank #1

Problem

Show the lowest ranking of product sales for store 1001.


Solution

SELECT storeid
,prodid
,sales
,RANK( ) OVER (ORDER BY sales ASC) AS "Rank"
FROM salestbl
WHERE storeid = 1001;

Result

storeid prodid sales Rank


----------- ------ ----------- -----------
1001 D 35000.00 1
1001 C 60000.00 2
1001 A 100000.00 3
1001 F 150000.00 4

Things To Notice:

 When the order of sales is ASC, the lowest sales amount is rank #1
 Rank #1 always appears at top of list unless overridden.

Rankings With Qualification

The QUALIFY clause allows restriction of which rankings will be output in the
final result. In the second query at hand, the QUALIFY clause restricts the result
to the top three sales amounts.

QUALIFY performs like the HAVING clause by requesting a specific range in the
output.

Problem

Get top 3 sales - any product in any store:

Solution

SELECT storeid
,prodid
,sales
,RANK( ) OVER (ORDER BY sales DESC)
AS "Ranking"
FROM salestbl
QUALIFY Ranking <= 3;

Result

storeid prodid sales Ranking


----------- ------ ----------- -----------
1001 F 150000.00 1
1001 A 100000.00 2
1003 B 65000.00 3

Things To Notice:

 QUALIFY shows the ranking for the top 3 sales amounts only.
 When the order of sales is DESC, the highest sales amount is rank #1

Note, salestbl data is shown here.

SELECT * FROM salestbl ORDER BY sales DESC;

storeid prodid sales


----------- ------ -----------
1001 F 150000.00
1001 A 100000.00
1003 B 65000.00
1001 C 60000.00
1003 D 50000.00
1002 A 40000.00
1001 D 35000.00
1002 C 35000.00
1003 A 30000.00
1002 D 25000.00
1003 C 20000.00

Variations On a Ranking

The RANK function produces an ordered sequence.


ORDER BY can override the normal sequencing.

Problem
Reverse the ranking sequence in the previous example.

Solution

SELECT storeid
prodid
,sales
,RANK( ) OVER (ORDER BY sales DESC) AS "Ranking"
FROM salestbl
QUALIFY Ranking <= 3
ORDER BY 4 DESC;

Result

storeid prodid sales Ranking


----------- ------ ----------- -----------
1003 B 65000.00 3
1001 A 100000.00 2
1001 F 150000.00 1

Things To Notice:

 The ORDER BY clause in the SELECT statement may always be used to


control the final order of the result set.
 When the order of sales is DESC, the highest sales amount is always rank
#1
 After the ranking is applied, the output results are produced based on the
ORDER BY sequence in the SELECT statement, if specified.

The following is an alternate way to produce the same result.

SELECT storeid
,prodid
,sales
,RANK( ) OVER (ORDER BY sales DESC) AS "Ranking"
FROM salestbl
QUALIFY Ranking <= 3
ORDER BY 3 ASC;

Result

storeid prodid sales Ranking


----------- ------ ----------- -----------
1003 B 65000.00 3
1001 A 100000.00 2
1001 F 150000.00 1

Things To Notice:

 The ORDER BY clause in the SELECT statement uses the sales column for
final ordering.

Ranking With PARTITION BY

The PARTITION BY clause may be used in conjunction with a RANK function to


change the scope of the ranking. Without a PARTITION BY clause, the scope
defaults to the RANK column. In the example on the preceding pages, the scope
was the sales amount and rankings were done strictly based on that amount.

In the example seen next, the PARTITION BY clause adds the store id to the
scope, thus rankings will be based upon sales within a store. Each store will have
its top three ranking sales output.

Whereas the RANK( ) ORDER BY clause controls the default sort key, the
PARTITION BY clause adds another level of sort to the output.

Problem

Get the top three selling products in each store.

Solution

SELECT storeid
,prodid
,sales
,RANK( ) OVER (PARTITION BY storeid
ORDER BY sales DESC) AS "Ranking"
FROM salestbl
QUALIFY Ranking <= 3;

Result

storeid prodid sales Ranking


----------- ------ ----------- -----------
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

Things To Notice:

 PARTITION BY clause controls scope, i.e., rank sales within store.


 Without PARTITION BY, scope would default to sales only.
 QUALIFY the ranking for the top 3 sales amounts per store.
 Sort sequence of output is sales descending.
 Due to PARTITION BY, sort is by sales (DESC) within store (ASC).
 Note -- no aggregation is done in this query.

Extended Ranking Scope

In the following example, an additional level of scope has been added via the
PARTITION BY clause. Our scope is now sales by product within store. Because
these three elements make up a ranking group and because the distinct
elements store and product only yield a single row, there are no rankings below
rank one. This is a case where the scope matches the granularity of the table,
thus no reasonable ranking can be produced.

Whereas the RANK( ) ORDER BY clause controls the default sort key, the
PARTITION BY clause adds another level of sort to the output.

Problem

Produce a ranking of sales by product within store.

Solution

SELECT storeid
,prodid
,sales
,RANK( ) OVER (PARTITION BY storeid, prodid
ORDER BY sales DESC) AS "Ranking"
FROM salestbl
QUALIFY Ranking <= 3;

Result

storeid prodid sales Ranking


----------- ------ ----------- -----------
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

Things To Notice:

 An additional PARTITION BY column is added.


 Scope is sales by product within store.
 Each product exists only once in each store.
 Thus, each row gets a rank of 1.

Note, the RANK function is covered in more detail in the Advanced SQL course.

The SAMPLE Function

The SAMPLE function is used to generate samples of data from a table or view.
This may be done in one of two ways. SAMPLE n - where n is an integer will yield
a sample of n rows, or if the number n is greater than the number of rows in the
table, the sample will consist of the number of rows in the table. Rows are not
reused within the same sample.

SAMPLE n - where n is a decimal value less than 1.00 and greater than .00

The SAMPLE function allows sampling of data based on:

 A percentage of a table.
 An actual number of rows.

Problem

Get a sampling of 10 employee numbers.

SELECT department_number
FROM employee
SAMPLE 10;

Result

department_number
-----------------
501
501
402
402
301
403
100
301
501
401

Things To Notice:

 This is just the first 10 arbitrarily selected rows.

When a percentage is specified, a fraction of the rows is returned based on the


decimal value. Note that calculations resulting in fractional rows must be greater
than .4999 to actually return a row.

In the following example, 25% of the rows of the employee table are to be
returned. The employee table has 26 rows.

26 * .25 = 6.50 = 7 rows in the sample

Example 2

Get a sampling of employee numbers using 25% of employees.

Solution

SELECT employee_number
FROM employee
SAMPLE .25
ORDER BY 1;
Result

employee_number
---------------
1005
1006
1011
1014
1018
1022
1024

Things To Notice:

 7 rows out of 26 are returned.


 Fractional results greater than .4999 generate an added row.
 25% of 26 = 6.5 which rounds to 7.

Using SAMPLEID

Multiple sample sets may be generated in a single query if desired. To identify


the specific set, a tag called the SAMPLEID is made available for association
with each set. The SAMPLEID may be selected, used for ordering, or used as a
column in a new table.

Problem

Get three samples from the department table, one with 25% of the rows,
another with 25% and a third with 50%.

SELECT department_number
,sampleid
FROM department
SAMPLE .25, .25, .50
ORDER BY sampleid;

Result

department_number SampleId
----------------- -----------
301 1
403 1
402 2
201 2
100 3
501 3
302 3
401 3
600 3

Things To Notice:

 Note that all 9 of the 9 rows of the department table are returned.
 This is due to the individual calculations.

Consider the following calculations

9 *.25 = 2.25 = 2
9 *.25 = 2.25 = 2
9 *.50 = 4.50 = 5
-----
9

Example 2

Get three samples from the department table, one with 27% of the rows,
another with 35% and a third with 2%.

Solution

SELECT department_number
,SAMPLEID
FROM department
SAMPLE .27, .35, .02
ORDER BY SAMPLEID;

Result

department_number SampleId
----------------- -----------
402 1
403 1
100 2
302 2
401 2

Things To Notice:

 The first two samples are able to return rows.


 The last sample is too small to return a row.
Example 3

Get three samples from the department table, one with 3 rows, another with 5
and a third with 8.

Solution

SELECT department_number
,sampleid
FROM department
SAMPLE 3, 5, 8
ORDER BY sampleid;

*** Query completed. 9 rows found. 2 columns returned.


*** Warning: 7473 Requested sample is larger than table rows.

Result

department_number SampleId
----------------- -----------
501 1
402 1
403 1
100 2
302 2
301 2
401 2
201 2
600 3

Things To Notice:

 Because the rows are not repeated to different sample sets, the supply of
rows is exhausted before the third set can be completed.
 This results in a warning that there were not enough rows to populate all
samples as requested.
 This warning is seen in the BTEQ environment, but not in ODBC.
 The third sample gets the only remaining row.

Stratified Sampling

Stratified samplings permit differing sampling criteria to be applied to different


sets of rows, all within a single query.
Problem

Get a sample which conforms to the following requirements:

 33% of people earning less than $30,000


 67% of people in the $30,001 - $40,000 range
 40% of people in the $40,001 - $50,000 range

Solution

SELECT employee_number AS Empno


,salary_amount AS Salamt
FROM employee SAMPLE
WHEN salary_amount < 30000 THEN .33
WHEN salary_amount BETWEEN 30001 AND 40000 THEN .67
WHEN salary_amount BETWEEN 40001 AND 50000 THEN .40
END
ORDER BY 2;

Result

Empno Salamt
----------- ------------
1014 24500.00
1023 26500.00
1009 31000.00
1005 31200.00
1022 32300.00
1025 34700.00
1004 36300.00
1012 37900.00
1024 43700.00
1010 46000.00

Things To Notice:

If no rows can support any stratified requirement then:

 No rows will be returned.


 No warning will be generated.

System Variables

The following system variables are available for use in creating SQL queries.
SESSION - contains the session-id of the requesting session/user.
DATABASE- contains the current default database of the requesting session/user.
USER - contains the user-id associated with the current session.
ACCOUNT - contains the user account info of the requesting session/user.

Each is defined internally as a VARCHAR(30).

Problem

Return the current session-id, default database, user-id and account string of the
current user.

Solution

SELECT SESSION, DATABASE, USER, ACCOUNT;

Result

Session Database User Account


----------- ---------- ---------------- ----------
30788 PED PED $MUSER

The default database setting may change during the course of a session. These
built-in functions allow you to keep track of your current database.

Problem

Show the current database both before and after it has been changed.

Solutions

SELECT DATABASE; /* Show the current database for this user


session*/

Database
------------------------------
PED

DATABASE cs_views; /* Change the default database for this user


session */

SELECT DATABASE; /* Show the new current database for this user
session*/
Database
------------------------------
cs_views
TOP N Overview

The TOP N function provides the ability to produce:

a. The top (or bottom) N rows of results based on specified criteria.


b. The top (or bottom) N percentage of rows based on specified criteria.
c. These results either with or without ties (more than one row has identical
criteria values).
d. Sample rows arbitrarily without regard to rankings or order.

This improvement has been achieved by implementing the following new syntax
to the SQL lexicon:

TOP {decimal | integer} [PERCENT] [WITH TIES]

The following meaning is associated with these options:

 TOP 10 – Return the top ten rows according to criteria


 TOP 15 PERCENT – Return the top 15% of rows according to criteria
 TOP 10 WITH TIES – If more that one row has the same criteria value,
return all
 TOP 15 PERCENT WITH TIES – If more than one row has the same
criteria value, return all

Show all department budgets ordered by budget amount descending. To answer


this query, the TOP N feature is not needed.

SELECT department_number
, budget_amount
FROM department
ORDER BY 2 DESC;
department_number budget_amount
----------------- -------------
401 982300.00
403 932000.00
301 465600.00
100 400000.00
402 308000.00
501 308000.00
201 293800.00
302 226000.00
600 ?

Note: Null sorts following the valid budget amounts.

TOP N With and Without TIES


Show the top five budget amounts.

SELECT TOP 5
department_number
, budget_amount
FROM department
ORDER BY 2 DESC;
department_number budget_amount
----------------- -------------
401 982300.00
403 932000.00
301 465600.00
100 400000.00
501 308000.00

Things to notice:

 ORDER BY defines the sequencing of the result set.


 It therefore defines the ranking criteria.
 To get the TOP highest amounts, you must use ORDER with DESC.
 TOP N where N is an integer up to 18 digits in length.

SELECT TOP 5 WITH TIES


department_number
, budget_amount
FROM department
ORDER BY 2 DESC;
department_number budget_amount
----------------- -------------
401 982300.00
403 932000.00
301 465600.00
100 400000.00
501 308000.00
402 308000.00

Things to notice:

 Even though TOP 5 is specified, six rows are returned.


 Because there is a tie for the fifth position, both rows are returned.
 This only occurs when WITH TIES is specified.
 WITH TIES returns multiple tied rows when there is a tie for the 'last'
position.
 It will return all rows containing the 'tied' value, but it will only count it as
one row.
 Tied rows which are not in the last position, are each counted separately
toward the N total.

The same result could have been retuned by specifying TOP 6 without the WITH
TIES option.

SELECT TOP 6
department_number
, budget_amount
FROM department
ORDER BY 2 DESC;
department_number budget_amount
----------------- -------------
401 982300.00
403 932000.00
301 465600.00
100 400000.00
501 308000.00
402 308000.00

Things to notice:

 The last two rows have the same amount.


 Each is counted as a separate row for the top six.
 By default, rows with the same amount are counted as separate rows
toward the total.
 The same result would be achieved if the WITH TIES option had been
specified.

Add the WITH TIES option and note any difference in the result set.

SELECT TOP 6 WITH TIES


department_number
, budget_amount
FROM department
ORDER BY 2 DESC;
department_number budget_amount
----------------- -------------
401 982300.00
403 932000.00
301 465600.00
100 400000.00
501 308000.00
402 308000.00

Things to notice:

 There is no difference.
 WITH TIES has no effect because the top six rows are requested.
 If a seventh row existed with the same amount as the sixth, it would be
returned.
 Note, that the same result is returned if we change the count to TOP 5.

SELECT TOP 5 WITH TIES


department_number
, budget_amount
FROM department
ORDER BY 2 DESC;
department_number budget_amount
----------------- -------------
401 982300.00
403 932000.00
301 465600.00
100 400000.00
501 308000.00
402 308000.00

Things to notice:

 The same result set is returned whether TOP 5 WITH TIES or TOP 6 is
specified.
 In this case, there is a tie for the 5th row, hence both rows are returned.
 If a seventh row existed with the same amount as the fifth and sixth, it
would also be returned.

Getting Bottom Results

Now, consider getting the rows at the bottom of an ordered list. This is
accomplished by using the ORDER BY clause.

Show the bottom three employees by salary.

SELECT TOP 3
employee_number
, salary_amount
FROM employee ORDER BY salary_amount ASC;
employee_number salary_amount
--------------- -------------
1014 24500.00
1013 24500.00
1001 25525.00
Things to notice:

 ORDER BY ASC reverses the ranking sequence and shows the bottom
rankings.
 Two rows with the same salary are treated as two rows of output.

What would you expect to happen if you add the WITH TIES option?

SELECT TOP 3 WITH TIES


employee_number
, salary_amount
FROM employee ORDER BY salary_amount ASC;
employee_number salary_amount
--------------- -------------
1014 24500.00
1013 24500.00
1001 25525.00

Things to notice:

 The WITH TIES option has no effect.


 Ties must occur in the last row returned to have any effect.
 If another row tied with the last row (25525.00), a fourth row would be
returned.

Add another 'tie row'.

INSERT INTO employee


VALUES (1026,801,401,201401,'Barnes','John',941230,800315,25525.00);

Get the bottom three employees by salary.

SELECT TOP 3
employee_number
, salary_amount
FROM employee ORDER BY salary_amount ASC;
employee_number salary_amount
--------------- -------------
1013 24500.00
1014 24500.00
1026 25525.00

Now add the WITH TIES option. Do you expect it to make a difference this time?

SELECT TOP 3 WITH TIES


employee_number
, salary_amount
FROM employee ORDER BY salary_amount ASC;
employee_number salary_amount
--------------- -------------
1014 24500.00
1013 24500.00
1026 25525.00
1001 25525.00

Things to notice:

 The WITH TIES option causes a fourth row to be returned.


 Ties must occur in the last row returned to have any effect.
 A tie with the last row (25525.00) returns a fourth row.

Selecting Random Rows

The TOP N function may also be used to return unordered rows. This is
accomplished by using TOP N without including an ORDER BY clause. In the
example seen here, two rows are requested. Since an unordered set cannot
produce the top n rows, the first n rows returned from the database are
selected. A second execution of the same query will produce the same two rows,
assuming that both the table and the configuration of the system have not
changed. This is because the database will return the rows in a consistent
sequence and always take the first (or top) n specified.

If a truly random sample is required, it is better to use the SAMPLE function


which has more randomized routines available.

Select two random rows.

SELECT TOP 2
employee_number
, salary_amount
FROM employee;

employee_number salary_amount
--------------- -------------
1008 29250.00
1012 37900.00

Things to notice:

 Absence of an ORDER BY clause means rows are returned without regard


to ranking.
 This is similar to using the SAMPLE function,
 The SAMPLE function however, produces a more truly randomized result
set.

Adding The WITH TIES Option

Add the WITH TIES option to the preceding query. What effect is seen?

SELECT TOP 2 WITH TIES


employee_number
, salary_amount
FROM employee;

employee_number salary_amount
--------------- -------------
1008 29250.00
1012 37900.00

Things to notice:

 Any two rows may be returned by this query, since no ranking criteria is
defined.
 Without an ORDER BY clause, the WITH TIES clause is ignored.
 This is similar to using the SAMPLE function, however the SAMPLE
function produces a more truly randomized result set.

Compared To BTEQ RETLIMIT

Previously, to return less than a full answer set, a user could use the .SET
RETLIMIT N option in BTEQ to control the number of rows returned to the client
side. Since the DBS must still generate all the result rows, the performance of
this approach could vary dramatically depending on the number of rows returned
by the SQL request. With the TOP N option, only the rows needed to satisfy the
query requirement are fetched by the DBS, thus making it a better choice when
a number of random rows are to be selected. The SAMPLE function continues to
be the preferred approach for truly random samples.

Using the PERCENT Option

The TOP N function can also produce a percentage of rows in addition to an


absolute number of rows.

Return employees whose salaries represent the top ten percent.


SELECT TOP 10 PERCENT
employee_number
,salary_amount
FROM employee ORDER BY salary_amount DESC;
employee_number salary_amount
--------------- -------------
801 100000.00
1017 66000.00
1019 57700.00

Things to notice:

 10% of 26 rows is 2.6 rows rounded to 3.


 PERCENT must be a number between 0 and 100.
 At least one row is always returned (if there is at least one row in the
table).
 A percentage resulting in a fractional number of rows is always rounded
up:
 10% of 6 rows = .6 rows = 1 row output
 20% of 6 rows = 1.2 rows = 2 rows output
 30% of 6 rows = 1.8 rows = 2 rows output

SELECT TOP 45 PERCENT WITH TIES


department_number
, budget_amount
FROM department
ORDER BY 2 DESC;
department_number budget_amount
----------------- -------------
401 982300.00
403 932000.00
301 465600.00
100 400000.00
501 308000.00
402 308000.00

Things to notice:

 45% of 9 rows is 4.05 rows rounded to 5.


 Because there is a tie for the fifth position, six rows are returned.

Notes About Using PERCENT:


If PERCENT is specified, the value of N must be a number greater than 0 and
less than or equal to 100. Fractional portions are permitted.

If PERCENT is not specified, the value of N may be up to the maximum decimal


value (18 digits), however a fractional portion may not be specified.
TOP N Parameterized

TOP n processing also permits the value of n to be passed into the operation by
means of a parameterized macro.

Create a parameterized macro which shows the top n budget amounts.

CREATE MACRO Top_Budgets (n INT) AS


(SELECT TOP :n
department_number
, budget_amount
FROM department
ORDER BY 2 DESC;);

Using the macro, show the top five department budgets.

EXEC Top_Budgets(5);
department_number budget_amount
----------------- -------------
401 982300.00
403 932000.00
301 465600.00
100 400000.00
501 308000.00

Lab

Try It! For this set of lab questions you will need information from
the Database Info document.

To start the online labs, click on the Telnet button in the lower
left hand screen of the course.
Two windows will pop-up: a BTEQ Instruction Screen and your
Telnet Window.
Sometimes the BTEQ Instructions get hidden behind the
Telnet Window.
You will need these instructions to log on to Teradata.

Be sure to change your default database to the


Customer_Service database in order to run these labs.

Click on the buttons to the left to see the answers.


Answers: A. Rank the top three departments in the ‘department’
Lab A table based on their budget_amount. Show department
Lab B number, budget amount and rank.
Lab C B. Create a report showing the store id, product id, sales
Lab D amount from the ‘salestbl’ and add a sales ranking by
product id.
Lab E
C. Modify Lab B to show the same report but limit it to
Lab F
each product id’s number one ranking i.e., eliminate all
Lab G
but the number one rankings.
Lab H D. Select the following information about your session
Lab I using built-in functions:
User Name
Session Id
Current Database
Account Id

Hint: Use the following settings to produce the output:


.SET FOLDLINE ON;
.SET SIDETITLES ON;
When the report has been created, reset the settings:
.SET FOLDLINE OFF;
.SET SIDETITLES OFF;

E. Create a table using the following description:

CREATE TABLE sqlxxx.empsamp


( empno INTEGER,
deptno INTEGER,
job INTEGER,
sampid BYTEINT)
UNIQUE PRIMARY INDEX ( empno );

Populate this table with three samples from the


employee table, identifiable by SAMPLEID 1, 2 and 3.
Let each sample contain 33% of the rows of the table.
Select all columns against the newly populated table
and order by results by SAMPLEID.

F. Delete the rows from empsamp and repopulate the


table with three samples of 15 rows each. Select the
resulting table and order by sampid to see the results
of this sampling.
G. Using the TOP N function, get the top three daily sales
amounts for the month of August 2004 from the
daily_sales_2004 table. Also retrieve the itemid and
salesdate.
H. Perform the same query using the WITH TIES option.
Is there a difference in the output?
I. Produce the same report as the previous lab, but add a
column showing the ranking of each row. Tied amounts
should show the same rank number.

19.) CASE Expressions

Case Expressions

Click on the link below to view the presentation on Case Expressions.

Please Note: This is a narrated presentation. You may control the pacing of this
module by using the Pause button as well as other buttons available on the
screen duing the presentation.

Start Presentation

After viewing the presentation, return to this window and continue to the next
lab activity

Lab

Try It! For this set of lab questions you will need information from
the Database Info document.

To start the online labs, click on the Telnet button in the lower
left hand screen of the course.
Two windows will pop-up: a BTEQ Instruction Screen and your
Telnet Window.
Sometimes the BTEQ Instructions get hidden behind the
Telnet Window.
You will need these instructions to log on to Teradata.

Be sure to change your default database to the


Customer_Service database in order to run these labs.

Click on the buttons to the left to see the answers.


Answers: A. Calculate the fraction of the total company budget
Lab A represented by departments 401 and 403. Express the
Lab B result as a percentage as follows:
B. 401/ 403
Lab C
C. Bgt Ratio
Lab D
D. ---------
E. xx%
F. Calculate the fraction of the total company budget
represented by departments 401 and 403 after
department 403 has been given a 5% budget increase.
Express the result as a decimal ratio as follows:
G. Dept_401_403_Bgt_Ratio
H. ----------------------
I. .xx
J. Create a budget report from the department table.
Show the total, average, minimum and maximum
budget amounts.
Title the columns "Total", Avg", "Min" and "Max".

Do the query twice:

a.) once treating NULL values as zero,


b.) once excluding NULL values in aggregates.

Compare the results.

K. Accounting wants to find out which way of slanting the


statistics is most beneficial to the company. Do a
departmental salary list of the total salaries for each
department, and the average departmental salary
three times:

- without any changes (treating NULLs as null and zero


values as zero)
- treating NULL values as zero
- treating zero values as NULL

Also list the count of rows that are going into each
averaging function. Sequence the report by
department. Limit the department number and count
columns to four digits each with zero suppress.

Title your columns as follows:

Dept Tot # Tot Sal Avg Sal ZIN # ZIN Avg


NIZ # NIZ Avg

Are there differences in these computations? Why or


why not?

20.) Views

Objectives

After completing this module, you should be able to:

 Create a view.
 Use a view to provide secure access to data.
 Drop or modify a view.
 List several reasons for using views.

What is a View?

A view functions like a 'window' into a table. It allows users to customize their
access to base tables by:

 Restricting which columns are visible from the base table.


 Restricting which rows are visible from the base table.
 Combining columns and rows from several base tables.

Restrict Columns from the Base Table

One can restrict columns from the base table(s) by explicitly listing the desired
column names from the base table(s) in the view definition.

Restrict Rows from the Base Table

One can restrict which rows may be accessed by using the WHERE clause in the
view definition. This will limit the rows returned from a SELECT statement
referencing the view.

Creating and Using Views

Problem

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.

Solution

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;

Result

employee_number last_name salary_amount


--------------- ------------- ---------------
1009 Lombardo 31000.00
1007 Villegas 49700.00
1012 Hopkins 37900.00
1005 Ryan 31200.00
1024 Brown 43700.00
1020 Charles 39500.00

To Update Through This View

UPDATE emp_403 SET salary_amount = 100000


WHERE last_name = 'Villegas' ;

What is a Join View?

A 'join view' consists of columns from more than one table.

Example

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;

Using this view permits SELECT of information from both tables. Note that
column names which appear in both tables (i.e., employee_number) must be
qualified.

Problem

Who is employee 1002 and what calls has he answered?

Solution

SELECT last_name
,first_name
,call_number
FROM employee_call
WHERE employee_number = 1002;

Result

last_name first_name call_number

Brown Alan 9

Renaming Columns

You may create a view that renames columns. This is often used to shorten long
column names, making queries easier to create.

Example

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;

Now you may SELECT rows using this view.

SELECT last
,sal
FROM shortcut
ORDER BY last DESC;

Result

last sal
------------ ----------
Short 38750.00
Morrissey 34700.00

To UPDATE rows using this View:

UPDATE shortcut
SET sal = 100000.00
WHERE emp = 1019;

Replacing a View

You may replace a view in order to include or drop specfic columns or values.

Problem

Change the shortcut view to include only department 301.

Solution

First, display the current view definition:

SHOW VIEW shortcut;

You should see the following view definition:

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;

Copy and paste the view definition to a text editor. Change the CREATE keyword
to REPLACE and make the desired 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;

Using Views For Formatting and Titles

The FORMAT clause may be used to set formats and the AS clause may be used
to assign new column names. For example, let's create a view for department
201 with shortened titles and appropriate formatting. Also, show the salary
amount as a monthly figure.

CREATE VIEW report AS


SELECT employee_number (FORMAT '9999') AS Emp
,department_number (FORMAT '999') AS Dept
,last_name (TITLE 'Name') AS Last
,first_name (TITLE ' ') AS First
,salary_amount / 12 (FORMAT '$$$,$$9.99')
AS Monthly_Salary
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 Jim $3,229.17

Aggregate Views

You may create a view that summarizes information by using aggregates. For
instance, let's 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;

Note: Aggregate and derived columns must be assigned names in the view
definition.

Select the average salary for all departments using the view we created:

SELECT department
,salary_average
FROM deptsals;
department salary_average
100 100000.00
201 36725.00
403 38833.33
... ...
401 35082.14

Aggregate View Using HAVING

The HAVING clause may be used within a view definition to restrict which groups
will participate in the view.

We may modify the deptsals view to include only departments with average
salaries 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;
To SELECT all departments with average salaries less than $36,000, we may use
the view deptsals as follows:

SELECT department
,salary_average
FROM deptsals;

department salary_average

------------- -----------------

401 35082.14

Joins on Views with Aggregates

Since views are really virtual tables, they may be joined with other tables and/or
views in a query.

Problem

First, create a view showing the the aggregate salaries by department number.

Solution

CREATE VIEW dept_salaries (deptnum, salaries)


AS
SELECT department_number, SUM(salary_amount)
FROM employee
GROUP BY 1;

Use the View to SELECT all rows:

SELECT *
FROM dept_salaries;

Results

deptnum salaries
----------- ------------
100 100000.00
201 73450.00
301 116400.00
302 56500.00
401 245575.00
402 77000.00
403 233000.00
501 200125.00

Now, let's look at another example, this time requiring a join.

Problem

Show by department name which departments have aggregate salaries greater


than $100,000.

Solution

SELECT deptnum
,department_name
,salaries
FROM dept_salaries ds INNER JOIN department de
ON ds.deptnum = de.department_number
WHERE salaries > 100000
ORDER BY 1;

Result

deptnum department_name salaries


----------- ------------------------------ ------------
301 research and development 116400.00
401 customer support 245575.00
403 education 233000.00
501 marketing sales 200125.00

Nested Aggregates

An aggregate result may be obtained from a view which has aggregation defined
in its creation. In the following example, an aggregated view is created.

CREATE VIEW dept_sals


AS SELECT department_number AS DEPT
,SUM (salary_amount) AS SumSal
FROM employee
GROUP BY dept;
SELECT all rows from the view:

SELECT *
FROM dept_sals
ORDER BY 1;

Result

dept SumSal
----- ---------
100 100000.00
201 73450.00
301 116400.00
302 56500.00
401 245575.00
402 77000.00
403 233000.00
501 201125.00

You may apply aggregate operators in your SELECT statement against the
aggregate view you just created. This represents aggregate functions being
applied to an aggregated view or what is referred to as 'nested aggregates'.

SELECT COUNT(Sumsal) AS #_Depts


,SUM(Sumsal) AS Total_Sals
,AVG(Sumsal) AS Avg_Dept_Tot
,MIN(Sumsal) AS Min_Dept_Tot
,MAX(Sumsal) AS Max_Dept_Tot
FROM dept_sals;

Result

#-Depts Total_Sals Avg_Dept_Tot Min_Dept_Tot Max_Dept_Tot


------- ---------- ------------ ------------ ------------
8 1102050.00 137756.25 56500.00 245575.00

Nested Aggregates in a WHERE Clause

Nested aggregates in a WHERE clause may be used to limit response rows.

Repeated for convenience:

CREATE VIEW dept_sals


AS SELECT department_number AS DEPT
,SUM (salary_amount) AS SumSal
FROM employee
GROUP BY dept;

Problem

Show the department with the highest total salary. .

Solution

SELECT dept
,Sumsal as Topsal
FROM dept_sals
WHERE topsal = (SELECT MAX(Sumsal)
FROM dept_sals);

Result

dept Topsal
---- ---------
401 245575.00
Things to notice:

 The aggregated view is used in both the main query and the subquery
 The subquery determines the maximum salary from the aggregate view.
 The main query uses the maximum salary to capture the department
number.

Views WITH CHECK OPTION

In a view, the WITH CHECK OPTION controls the update and insert capability of
users with those privileges on the view. A user may not insert or update a row if
the resulting row will fall outside of the view. Said differently, an insert or update
will be denied if the resulting row will violate the constraints of the WHERE clause
in the view definition.

For example, let's recreate a view and add a WHERE clause and a WITH CHECK
OPTION:

REPLACE VIEW dept_budget AS


SELECT department_number AS Dept
,department_name AS Name
,budget_amount AS Budget
,manager_employee_number AS Mgr
FROM department
WHERE Budget <= 1000000
WITH CHECK OPTION;

With the WITH CHECK OPTION in place in a view, the following inserts and
updates are affected:

 New departments may not be inserted if the budget amount is above


$1,000,000.
 A department budget may not be updated to be more than $1,000,000.

Changing Rows Via the View

Users will not be able to update or insert rows whose values violate the
constraints of the WHERE clause in the view definition.

Example 1

INSERT INTO dept_budget


VALUES (601, 'Support', 2000000, 1018);

**** Failure 3564 Range constraint:Check error in field


dept.budget_amount.

Example 2

UPDATE dept_budget
SET budget = 2000000
WHERE dept = 401;
**** Failure 3564 Range constraint:
Check error in field dept.budget_amount.
Both operations above were disallowed because the WITH CHECK OPTION
prevents these changes.

Restrictions and Advantages With Views

Restrictions When Using 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 and aggregated columns must be assigned a name using one of
the following techniques:
o NAMED clause.
o AS clause (ANSI standard).
o Creating a list of assigned column names in the CREATE VIEW
definition.
 A view cannot be used to UPDATE if it contains:
o Data from more than one table (Join View).
o The same column twice.
o Derived columns.
o A DISTINCT clause.
o A GROUP BY clause.

Advantages When Using Views

 An additional level of security.


 Help in controlling read and update privileges.
 Simplify end-user's access to data.
 Are unaffected if a column is added to a table; and
 Are unaffected if a column is dropped, unless the dropped column is
referenced by the view.

Suggestions For Using Views

 Create at least one view for each base table to restrict user's access to
data they don't need to see.
 Create query views as you need them for ad hoc situations.
 Use access locks when creating views to maximize data availability to
users.

Lab

Try It! For this set of lab questions you will need information from
the Database Info document.

To start the online labs, click on the Telnet button in the lower
left hand screen of the course. Two windows will pop-up: a
BTEQ Instruction Screen and your Telnet Window.

Sometimes the BTEQ Instructions get hidden behind the


Telnet Window. You will need these instructions to log on to
Teradata.

Hint: Prior to doing these labs, it will be helpful to reset


your default database to your own user id (i.e.
DATABASE tdxxx;).

Click on the buttons to the left to see the answers.

Answers: A. List the customer number, customer name, and sales


Lab A representative's number for customers in California.
Lab B Sort by sales representative's number.
Lab C
Lab D HINT: The location table contains both the customer
number and the state.
Lab E

Now modify the request to use a join instead of a


subquery.

Now create a VIEW called "sales_territory".

Do not create it as part of a macro. Is data in this view


updatable?

B. Select all columns from the sales_territory view.


C. Create an aggregate view called "dept_sal" which
accesses the customer_service.employee table and
consists of two columns: a department number and the
sum of the salaries for that department. Select all rows
from this view.
D. Using the ‘dept_sal’ view, produce a report showing
department name and total departmental salary for
each department whose total exceeds $100,000.

Remember: Like tables and macros, views must be


created in your own database.

E. Create a full view of any table in the customer_service


database. Include formatting and titling of your own
choosing. Select all rows and columns from your view
to observe how the view overrides default formats and
column headings.

21.) String Functions


Objectives

After completing this module, you should be able to:

 Extract strings using SUBSTRING.


 Combine strings using concatenation.
 Locate the starting position of substrings.

String Expressions

Several functions are available for working with character strings in SQL. Also,
the concatenation operator is provided for combining strings. The string
functions and the concatenation operator are listed here.

String Operator Description

|| (Two vertical
Concatenates (combines) character strings together.
bars)

String Functions

Obtains a section of a character string. (Teradata


SUBSTR
extension)
SUBSTRING Obtains a section of a character string. (ANSI standard)

Locates a character position in a string. (Teradata


INDEX
extension)
POSITION* Locates a character position in a string. (ANSI standard)
TRIM* Trims blanks from a string.
UPPER* Converts a string to uppercase.
LOWER* Converts a string to lowercase.

All functions listed are part of the ANSI standard except for:

 INDEX which has an ANSI equivalent POSITION function, and


 SUBSTR which has an ANSI equivalent SUBSTRING.

*These topics are introduced elsewhere in the SQL course sequence.

POSITION, UPPER and LOWER are covered in more detail in the Teradata SQL For
Application Development course.
The TRIM function was covered in a previous module of this course.

SUBSTRING Function

The SUBSTRING function is intermediate-level ANSI compliant. Teradata


continues to support the alternate SUBSTR syntax as well.

Examples

SELECT SUBSTRING ('catalog' FROM 5 for 3);

Result

'log'
SELECT SUBSTR ('catalog',5,3);

Result

'log'

Let's look at several more examples showing the results of a SELECT using either
SUBSTRING or SUBSTR . Equivalent results are returned in all cases.

SUBSTRING SUBSTR
Result Result

SUBSTRING(‘catalog’ FROM 5 FOR 4) ‘log’ ‘log’

SUBSTRING(‘catalog’ FROM 0 FOR 3) ‘ca’ ‘ca’

SUBSTRING(‘catalog’ FROM -1 FOR 3) ‘c’ ‘c’

SUBSTRING(‘catalog’ FROM 8 FOR 3) 0 length string 0 length string

SUBSTRING(‘catalog’ FROM 1 FOR 0) 0 length string 0 length string

SUBSTRING(‘catalog’ FROM 5 FOR -2) error error

(without a FOR clause)

SUBSTRING(‘catalog’ FROM 0) ‘catalog’ ‘catalog’

SUBSTRING(‘catalog’ FROM 10) 0 length string 0 length string


SUBSTRING(‘catalog’ FROM -1) 0 length string 0 length string

SUBSTRING(‘catalog’ FROM 3) ‘talog’ ‘talog’

Since the Teradata extension provides equivalent functionality to the ANSI-


compliant feature, we recommend that all existing applications replace any use
of the SUBSTR function with the SUBSTRING function.

Using a SUBSTRING in a List

Problem

Display the first initial and last name of all employees in department 403. Sort
the result by last name.

Solution

SELECT SUBSTRING (first_name FROM 1 FOR 1) AS FI


,last_name
FROM employee
WHERE department_number = 403
ORDER BY last_name
;

Result

FI last_name
-- --------------------
A Brown
J Charles
P Hopkins
D Lombardo
L Ryan
A Villegas

Using SUBSTRING with INTEGERS

A SUBSTRING function can also be performed on numeric data. Internally, the


numeric data must be converted to a character string before the SUBSTRING
function can occur. Because SUBSTRING relies on the exact position of each
character, care must be taken when performing this function with numerics.

The following gives examples of how integers are converted when a SUBSTRING is
performed on them.

These three column definitions are used in the example below:

Column Data Type and Conversion Size

no_of_
BYTEINT - (3 digits) 4 characters including sign
dependents

SMALLINT - (5 digits) 6 characters including


area_code
sign

INTEGER - (10 digits) 11 characters including


phone
sign

When an integer field is converted to CHAR, a sign character is added and the
value is right-aligned as follows:

+ 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)

Problem

Produce a list of all 3-digit area codes from the location_phone table.

Solution

SELECT DISTINCT SUBSTRING (area_code FROM 4 FOR 3)


AS AREA_CODE
FROM location_phone
ORDER BY 1;

Result

AREA CODE
202
212
213
312
313
415
609
617
718
804
919

Using SUBSTRING in a WHERE Clause

Problem

Find those customers in the location table whose nine-digit zip code ends with
four zeros.

Solution

SELECT customer_number
,zip_code (FORMAT '9(9)')
FROM location
WHERE SUBSTRING (zip_code FROM 8 FOR 4) = '0000'
;

Result

customer number zip code


13 001210000
10 940710000

String Concatenation

Multiple strings may be combined using the string concatenation operator '||'.
Only character and byte data types may be concatenated. (Byte data types must
be concatenated with another byte data type.)

Use either solid (or broken) vertical bars || as a concatenation operator.


Example

SELECT 'abc' || 'xyz';

combines the two strings into a single character string.

Result

'abcxyz'

Concatenation and the COALESCE Function

Normally, concatenation of any string with a null produces a null result.

The COALESCE function allows values to be substituted for nulls.

Example

Assume col1 = 'a', col2 = 'b'

SELECT col1 || col2 From tblx;

Result

'ab'

If either column contains a null, the result is null.

Example

Assume col1 = 'a', col2 = null

SELECT col1 || (COALESCE (col2,'x')) FROM tblx;

Result

'ax'

Teradata Alternative

The Teradata database also supports the use of exclamation marks (!!) as the
concatenation operator. Existing applications using exclamation marks should be
re-written using vertical bars to meet ANSI standards.

Problem

Display the first and last names for employees in department 403.

Solution

SELECT first_name || ' ' || last_name


AS EMPLOYEE
FROM employee
WHERE department_number = 403 ;

Result

EMPLOYEE
Arnando Villegas
Loretta Ryan

Things to notice:

 The concatenation operators are used to place a space between first and
last name.
 Even though two columns are concatenated together, it is treated as a
single column of output.
 There are no commas in this statement, since there is only one column of
output.

String Concatenation with SUBSTRING and TRIM

SUBSTRING and concatenation may be used together in a query.

Problem

Display the first initial and last name of employees in department 403.

Solution

SELECT SUBSTRING (first_name FROM 1 FOR 1 ) || '. ' ||


last_name AS EMPLOYEE
FROM employee
WHERE department_number = 403 ;

Result

EMPLOYEE
-----------------------
D. Lombardo
A. Villegas
P. Hopkins
L. Ryan
A. Brown
J. Charles

Problem

Produce the same list, but concatenate last name followed by first name
separated by a comma.

Solution

SELECT last_name || ', ' || first_name


AS EMPLOYEE
FROM employee
WHERE department_number = 403 ;

Result

EMPLOYEE
-------------------------------------
Lombardo , Domingus
Villegas , Arnando
Hopkins , Paulene
Ryan , Loretta
Brown , Allen
Charles , John

Things to notice:

 The column last_name is defined as a fixed length CHAR(20).


 Consequently, there will be a number of spaces following each last name.
 This can be corrected with the use of the TRIM function .

Use the TRIM function to remove the extra spaces in your query result.
Problem

Drop the spaces after the last names prior to concatenating with the first name.

Solution

SELECT TRIM (last_name) || ', ' || first_name


AS EMPLOYEE
FROM employee
WHERE department_number = 403 ;

Result

EMPLOYEE
-------------------
Lombardo, Domingus
Villegas, Arnando
Hopkins, Paulene
Ryan, Loretta
Brown, Allen
Charles, John

The POSITION Function

The POSITION function finds the position within a string where a specified
substring begins. The ANSI standard POSITION function has a Teradata
equivalent function called INDEX. The INDEX function will continue to be
supported in future releases of the product, however the use of POSITION is
encouraged for future applications.

Both the POSITION and INDEX functions return a character position in a string.

Examples of the POSITION function

SELECT POSITION( 'b' IN 'abc'); Result:2


SELECT POSITION( 'ab'IN 'abc'); Result:1
SELECT POSITION( 'd' IN 'abc'); Result:0

Comparable examples of the INDEX function.

SELECT INDEX('abc', 'b'); Result:2


SELECT INDEX('abc', 'ab'); Result:1
SELECT INDEX('abc', 'd'); Result:0

POSITION will be used for subsequent examples.

SUBSTRING and POSITION functions may be used together in a query.

Problem

Display a list of departments where the word "SUPPORT" appears in the


department name, and list the starting position of the word.

Solution

SELECT department_name
,POSITION('SUPPORT' IN department_name)
FROM department
WHERE POSITION('SUPPORT' IN department_name) > 0
ORDER BY department_number;

Result

DeptName PositionNum
------------------------------ -----------
customer support 10
software support 10
Note: POSITION is discussed in more detail in the Teradata SQL For Application
Development course.

Using SUBSTRING and POSITION

Use of SUBSTRING and POSITION may be necessary to 'normalize' a character


string column which is really two column values combined into a single column. In
this case, the column 'contact_name' contains both first and last name. These
functions may be used to separate them and to produce a different report format,
in this case, first name followed by last.

The Contact table, seen below, is used with this example.

Problem

Display the first name and last names separated by a single space for each person
in the contact table.
Solution

SELECT SUBSTRING (contact_name FROM


POSITION (',' IN contact_name) +2) || ' ' ||
SUBSTRING (contact_name
FROM 1 FOR POSITION (',' IN contact_name) -1)
AS "Contact Names"
FROM contact;

Result

Contact Names
--------------------------
Jack Hughes
Nancy Dibble
James Leblanc
Ginny Smith
Alison Torres
Connie Brayman

Things to notice:

 The column contact_name is defined as a variable length VARCHAR(30).


 First and last name are stored in the colunm as seen in the table below.
 To reposition first and last name, the POSITION function is used to search
for a comma.
 This type of string manipulation is necessary when data is not properly
normalized.
 If first and last name were separate columns, this manipulation would be
unnecessary.
Lab

Try It! For this set of lab questions you will need information from
the Database Info document.

To start the online labs, click on the Telnet button in the lower
left hand screen of the course. Two windows will pop-up: a
BTEQ Instruction Screen and your Telnet Window.

Sometimes the BTEQ Instructions get hidden behind the


Telnet Window. You will need these instructions to log on to
Teradata.

Be sure to change your default database to the


Customer_Service database in order to run these labs.

Click on the buttons to the left to see the answers.


Answers: A. Select last and first name, area code and phone
Lab A number for employees in the 609 area code. Limit first
Lab B name to 10 characters. You will need to join the
Lab C employee and the employee_phone tables to
Lab D accomplish this. Use table name aliasing for your join.
Display your output in the format below:
B. last_name first_name Phone
Number
C. -------------------- ---------- -----------
--
D. Johnson Darlene (609)559-
1011
E.

Hint: Use substringing and concatenation to solve this


lab.

Note: This lab is used again in exercise C.

F. Find all jobs that have the word "Analyst" in their


descriptions. List the descriptions and positions where
the character strings are found.
G. Modify exercise A to concatenate the phone extension
with the rest of the phone number. Use COALESCE to
transform any NULLs in the extension column into zero.
Give the concatenated phone expression the following
title, appropriately lined up over the data:
H.
I. Phone Number Ext

J. --------------------
K. (xxx) xxx-xxxx xxx
L. List all contacts from the contact table, breaking the
first name out into its own column and the last name
into its own column. Include phone number. Select
only contacts in area code 408. Sort by first name.
Custom column titles for the name columns are: First
Name and Last Name.

Note: The format of the contact table is shown here


for your reference.

CREATE TABLE contact,


FALLBACK
(contact_number INTEGER
,contact_name CHAR(30) NOT NULL
,area_code SMALLINT NOT NULL
,phone INTEGER NOT NULL
,extension INTEGER
,last_call_date DATE NOT NULL)
UNIQUE PRIMARY INDEX (contact_number);

Note: The column 'contact_name' is denormalized,


meaning that there are two pieces of information in
one column. This situation often makes string
manipulation necessary.

S-ar putea să vă placă și