JDB SQL Reference |
This chapter includes an explanation of the SQL commands and concepts in alphabetical order. You can execute the SQL commands described in this chapter using JPL procedures or using JISQL. For an example, refer to page 3-10.
Reference Organization |
The reference material is listed alphabetically for the following topics:
CREATE DATABASE
CREATE TABLE
DELETE
DROP DATABASE
DROP TABLE
INSERT
SELECT
UPDATE
BETWEEN
GROUP BY
HAVING
LIKE
ORDER BY
WHERE
Aggregate Functions
Data Types
Joins
Null Values
Operators
Subqueries
This chapter includes a section for each command or topic. Each section can include the following subsections:
The examples included in this section use the JISQL syntax and are based on the videobiz database. For a complete description of this database, refer to Figure 2-2 or Appendix D, "Videobiz Database."
Aggregate Functions
Obtain information about rows or groups of rows
functionName
([DISTINCT]expression
)
functionName
- One of the following aggregate functions:
AVG
,COUNT
,MAX
,MIN
orSUM
.DISTINCT
- Eliminates duplicate values before the function is applied. This keyword can be used with
AVG
,COUNT
orSUM
. It is not allowed withCOUNT
(*),MAX
orMIN
.expression
- A constant, column name, subquery, or any combination of these connected by arithmetic or bitwise operators (
AND
andOR
).
Aggregate functions calculate different types of summary information on rows in a database table. All of the aggregate functions ignore null values, with the exception of
COUNT
(*). Table 6-1 lists the aggregate functions supported in JDB.
Aggregate functions generally appear in a select list, in a
HAVING
clause, or in conjunction with aGROUP BY
clause. When used in the same statement as aGROUP
BY
clause, aggregate functions return summary information on each group of data. Aggregate functions are not valid in theWHERE
clause ofSELECT
statements.
The following statement finds the number of video titles entered in the database by querying for a count of the rows in the
titles
table:SELECT COUNT(*) FROM titles;
The following statement uses the
DISTINCT
keyword to calculate the number of video titles that have a copy of the tape available for rental.SELECT COUNT(distinct title_id) FROM tapes WHERE status = 'A';
The following statement calculates the average number of rentals per customer and the average rental amount:
SELECT AVG(num_rentals), AVG(rent_amount) FROM customers;
The following statement queries for the least number of times a copy of a video has been rented:
SELECT MIN(times_rented) FROM tapes;
The following statement calculates the money collected from video rentals for a particular day:
SELECT SUM(amount_paid) FROM rentals
WHERE rental_date LIKE '1993/10/22%';
The following statement calculates the number of times a particular title has been rented:
SELECT SUM(times_rented) FROM tapes
WHERE title_id = 12;
Specify a range of data values
[NOT] BETWEEN x AND y
The
BETWEEN
predicate, located in the WHERE Clause, specifies a range of database values to be used in determining a result set. The range specified is inclusive of x and y.If the
NOT
keyword is specified, only rows outside the specified range are included in the result set.
The following statement lists videos whose length is between an hour and two hours:
SELECT title_id, name, film_minutes FROM titles
WHERE film_minutes BETWEEN 60 AND 120;
The following statement deletes all the film rentals that occurred in 1989:
DELETE FROM rentals WHERE rental_date
BETWEEN '1989/01/01 00:00:00' AND '1989/12/31 23:59:59';The following statement finds which current customers live in a series of postal codes:
SELECT cust_id, first_name, last_name FROM customers
WHERE postal_code BETWEEN 10200 AND 10299
AND member_status <> 'I';
The following statement performs the same query, finding the current customers in the designated series of postal codes, without the
BETWEEN
predicate:SELECT cust_id, first_name, last_name FROM customers
WHERE postal_code >= 10000 AND postal_code <= 10199
AND member_status <> 'I';
Create a new database
CREATE DATABASEdatabase-name
database-name
- A unique identifier for the database. Since the database appears as a file on the operating system, its identifier must follow the naming conventions for the operating system. If the database name contains characters that are not alphanumeric or if you are including a path name, the name must be enclosed in single quotation marks.
The
CREATE DATABASE
statement creates a new database. A database must be created before you can declare a connection to it. You can create a database when you are connected to JDB using the identifier @system
, when you are connected to another JDB database, or when you are using JISQL.Creating the First Database
You can create your first database in JDB either by using JISQL or by writing a JPL procedure.
- JISQL
- To create the database in JISQL, first you need to start the program. For UNIX systems, it is usually located in
$SMBASE/util
. To start it, type:jisqlOr, click on the JISQL icon.
The JDB ISQL window opens.
To create the database, choose DatabaseCreate Database. The Create Database window opens.
Enter the name of the database you want to create, select the Connect after creation check box, and choose OK. This creates the database and automatically connects to it so that you can then create database tables.
- JPL
- The equivalent JPL procedure is as follows:
dbms declare syscon connection for database @system
dbms run create databasedatabase-name
dbms close connection syscon
dbms declare c1 connection for databasedatabase-name
dbms run create tabletable-name
...
CREATE DATABASE videobiz;If the database name contains non-alphanumeric characters or if you are including a path name, enclose the name in single quotation marks:
CREATE DATABASE 'video.db';CREATE DATABASE '/usr/home/videobiz';
Creates a new database table
CREATE TABLEtable-name
(
column-namedata-type
[(length
)] [NOT NULL] [,column-name
...]
[PRIMARY KEY (column-name
[,column-name
... ] ), ]
[UNIQUE (column-name
[,column-name
... ] ), ]
[FOREIGN KEY (column-name
[,column-name
... ] )
REFERENCEStable-name
(column-name
[,column-name
...]) [ ,] ]
)
table-name
- Identifier for the table to be created. This identifier must be unique to the database. Identifiers in JDB must start with a letter but may contain letters, numbers, and underscores.
column-name
- Identifier for the column. Each column identifier must be unique within the table.
data-type
- Data type for the column. For char data types, a
length
must also be specified. For more information on data types, refer to page 6-15.NOT NULL
- Specifies that a value must be entered for the column. The value for the column cannot be null.
PRIMARY KEY
- Specifies the primary key column(s) for this table. Any column specified as a primary key must be specified as
NOT NULL
.UNIQUE
- Specifies that a column or group of columns must contain a unique entry. Any column specified as unique must be specified as
NOT NULL
. Column(s) specified in aPRIMARY KEY
clause do not need to be declared asUNIQUE
.FOREIGN KEY
- Specifies the foreign key columns for this table. Any such column must refer to a primary or unique key in the referenced table. Matching between the foreign and primary keys is performed in the order the columns are listed, not by their names.
REFERENCES
- Specifies the database table and the column name in that table for the foreign key column. If more than one column is listed, the order of the columns listed in the
FOREIGN KEY
clause must match the order of the columns in theREFERENCES
clause.
The
CREATE TABLE
statement creates a new table in the current database with the specified columns. For each column, you must specify the following:
- Column name
JDB is a case-insensitive database system. No matter which case you use to enter your table and column names, JDB stores the names in lower case.
Specify Primary and Foreign Keys
You need to specify the primary and foreign keys when you create the table. The primary key is the column containing a different value in every row, which ensures that all rows are unique. In cases where one column does not perform this function, you must specify two or more columns whose values together form a unique entry. This is called a composite key. Null values are not allowed in the primary key columns; therefore, the column definitions for those columns should contain the keyword
NOT NULL
.Foreign keys are columns in the database table that are primary or unique keys in another database table. Data entered into a foreign key column should exist as a value in the other database table. The data type for the foreign key column and its corresponding primary or unique key must be the same.
Although JDB does not enforce referential integrity based on your primary and foreign keys, it is recommended that you enter primary and foreign key information for your database tables.
Maximum Row Length
In JDB, there is a maximum row length of 1K. In other words, the sum of the table's column sizes cannot exceed 1K. The base length of the various columns is:
Data type Base length
CHAR
Specified length
INT
4 bytes (stored as
LONG
in the current release)
LONG
4 bytes
FLOAT
12 bytes
DOUBLE
12 bytes
DATETIME
9 bytes
The length of a column is defined as its base length plus an additional 2 bytes for flags.
The following statement creates a table whose size equals 1028 ((255+2) * 4). Since that total is greater than 1024, JDB reports the error "Maximum record length exceeded."
CREATE TABLE toobig (
a CHAR (255),
b CHAR (255),
c CHAR (255),
d CHAR (255));
The following statement creates the actors table with
actor_id
as the primary key:CREATE TABLE actors (
actor_id INT NOT NULL,
last_name CHAR ( 25) NOT NULL,
first_name CHAR ( 20) ,
PRIMARY KEY (actor_id));The following statement creates the rentals table:
CREATE TABLE rentals (
cust_id INT NOT NULL,
title_id INT NOT NULL,
copy_num INT NOT NULL,
rental_date DATETIME NOT NULL,
due_back DATETIME NOT NULL,
return_date DATETIME ,
price FLOAT NOT NULL,
late_fee FLOAT NOT NULL,
amount_paid FLOAT NOT NULL,
rental_status CHAR ( 1) NOT NULL,
rental_comment CHAR ( 76) ,
modified_date DATETIME NOT NULL,
modified_by CHAR ( 8) NOT NULL,
PRIMARY KEY (cust_id, title_id, copy_num, rental_date),
FOREIGN KEY (cust_id) REFERENCES customers (cust_id),
FOREIGN KEY (title_id, copy_num)
REFERENCES tapes (title_id, copy_num),
FOREIGN KEY (modified_by) REFERENCES users (user_id));
List the data types available in JDB
The JDB data types are described in this section.
CHAR
(n)- Character column containing ASCII characters (letters, numbers and symbols). Specify the maximum size of the column with n. n can range in value from 1 to 255. The size of a
CHAR
column is n no matter how many characters are entered into the column. If the character string is longer than n, the string is truncated to the specified length. If the character string is shorter than n, the string is blank-padded to the specified length. For example, an entry of
'A12'
in aCHAR
(4) column would be stored as
'A12 'The storage size of a
CHAR
column is n plus 2 bytes for flags.To enter values into
CHAR
columns using JISQL, enclose the character string in single quotation marks. To include a single quotation mark as part of the entry, enter two consecutive single quotation marks.If you use colon plus processing or binding in a JPL procedure, Panther automatically formats the character string by enclosing the character string in single quotation marks and converting each single quotation mark to two single quotation marks.
INT
- Numeric column containing whole numbers. In the current version of JDB, all
INT
values are stored asLONG
values.- LONG
- Numeric column containing whole numbers ranging from -2,147,483,647 to +2,147,483,647. The storage size for an
LONG
column is 4 bytes plus 2 bytes for flags.- FLOAT
- Numeric column containing positive or negative floating point numbers. The hardware platform determines the precision and range of
FLOAT
columns. The storage size is 12 bytes plus 2 bytes for flags.- DOUBLE
- Numeric column containing double precision numbers. The hardware platform determines the precision and range of
DOUBLE
columns. The storage size is 12 bytes plus 2 bytes for flags.- DATETIME
- Date column containing both a date and time of day. The storage size is 9 bytes, plus 2 bytes for flags. The default format for a
DATETIME
column is:
yyyy/mm/dd hh:mm:ssFor example, January 28, 1993 at 2:40 p.m. is entered as follows:
1993/01/28 14:40:00
Alternate formats for
DATETIME
values include using periods instead of colons to separate time entries and using spaces instead of slashes to separate date entries.To enter
DATETIME
values in JISQL, enclose the date entry in single quotes as in:'1993/01/28 14:40:00'
To enter
DATETIME
values in JPL, the date should both be enclosed in single quotes and contain double colons:DBMS RUN UPDATE titles \
SET release_date = '1994/01/28 00::00::00' \
WHERE title_id = :+title_idIf
DT_DATETIME
is the Panther type of the widget containing the entry, Panther automatically formats the date according to the specified Date/Time format.The data type of each column is stored in the system table,
syscols
. You can query this table to find the data type for any column. Refer to page 4-3 for more information on thesyscols
table.Numeric Columns
In JDB, you cannot enter numbers with leading zeros in numeric columns.
The following statement creates the titles table:
CREATE TABLE titles (
title_id INT NOT NULL,
name CHAR ( 60) NOT NULL,
genre_code CHAR ( 4) ,
dir_last_name CHAR ( 25) ,
dir_first_name CHAR ( 20) ,
film_minutes INT ,
rating_code CHAR ( 4) ,
release_date DATETIME ,
pricecat CHAR ( 1) NOT NULL
PRIMARY KEY (title_id),
FOREIGN KEY (pricecat) REFERENCES pricecats (pricecat));The
titles
table contains columns of various data types. The following statement inserts a row into this table:INSERT INTO titles (title_id, name, genre_code,
dir_last_name, dir_first_name, film_minutes, rating_code,
release_date, pricecat)
VALUES (72, 'Howards End', 'DRAM', 'Ivory', 'James', 140,
'PG', '1992/01/01 00:00:00', 'G');
Remove information from a database table
DELETE FROMtable-name
[WHEREsearch-conditions
]
table-name
- Identifier for the database table.
WHERE
- The
WHERE
clause specifies which rows will be deleted. Refer to page 6-54 for more information on theWHERE
clause.
The
DELETE
statement removes a row or rows from the specified table. To keep data consistent across a database, you may need to delete or update rows in other database tables whose values depend on the deleted row.Warning: If no
WHERE
clause is specified, all the information in the table is deleted.
If a customer drops his membership, you can delete that customer from the database:
DELETE FROM customers WHERE cust_id = 123;To delete a video title from the database, you would need to delete rows from titles,
title_dscr
, tapes and roles:DELETE FROM title_dscr WHERE title_id = 134;
DELETE FROM roles WHERE title_id = 134;
DELETE FROM tapes WHERE title_id = 134;
DELETE FROM titles WHERE title_id = 134;You can delete rows using a subquery in the
WHERE
clause:DELETE FROM actors WHERE actor_id IN
(SELECT actor_id FROM roles WHERE title_id = 134);
WHERE Clause
Remove a database
DROP DATABASEdatabase-name
database-name
- Name of the database to be removed.
The
DROP DATABASE
statement deletes the specified database. The file containing the database is removed from the operating system. If the database name contains characters that are not alphanumeric, enclose the name in single quotation marks.You cannot drop the current database. First, you must close the connection with the current database and connect either to another database or to the system catalog.
When you drop a database, the journal files are not deleted.
DROP DATABASE videobiz;Enclose the name in single quotation marks if it contains non-alphanumeric characters.
DROP DATABASE 'video.db';
Remove a table from the database
DROP TABLEtable-name
table-name
- Name of the table to be deleted.
The
DROP TABLE
statement deletes the specified table from the database, including the data stored in the table.
DROP TABLE rentals;
Divide the returned data into groups according to the specified column(s)
GROUP BY [correlation-name
.column-name
[ , ... ]
correlation-name
- Identifier which substitutes for the table name.
column-name
- Column used to group the data.
A
GROUP BY
clause included in aSELECT
statement lets you specify the column or columns to be used to divide the table into groups. Rows having an identical value in the specified columns are grouped together.A
GROUP BY
clause is most often combined with an aggregate function in order to obtain summary information on each group. AGROUP BY
clause can also be followed by aHAVING
clause in order to define which groups appear in the result set.In a
SELECT
statement containing aGROUP BY
clause, the columns specified in the select list or in theHAVING
clause must either be listed in theGROUP BY
clause or be parameters of aggregate functions.
This statement finds the number of videos in each rating category:
SELECT rating_code, COUNT(*) FROM titles
GROUP BY rating_code;
A
GROUP BY
clause can be used to find unique entries in aSELECT
statement; however, theDISTINCT
generally used for this purpose. The following statement lists the types of videos found in the titles table:SELECT genre_code FROM titles GROUP BY genre_code;
This statement using both a
GROUP BY
clause and aHAVING
clause determines the people who directed more than three videos:SELECT dir_last_name FROM titles GROUP BY dir_last_name
HAVING COUNT(*) > 3;
If your
SELECT
statement also includes aWHERE
clause, place theGROUP BY
clause afterWHERE
clause.SELECT title_id, COUNT (*) FROM tapes WHERE status = 'A'
GROUP BY title_id;
Set search conditions in order to obtain a subset of data
HAVINGsearch-conditions
search-conditions
- Specifies the conditions for the selection of data. For a complete listing of available conditions, refer to page 6-54.
A
HAVING
clause included in aSELECT
statement allows you to select a subset of data which has a certain value.Generally, a
HAVING
clause appears in conjunction with aGROUP BY
clause. When this occurs, theHAVING
clause selects its subsets after theGROUP BY
clause has been applied.Unlike the
WHERE
clause, aHAVING
clause can include aggregate functions.In statements using both a
WHERE
clause and aHAVING
clause, the following steps occur:
- The
WHERE
clause selects the rows meeting its search conditions.- The
GROUP BY
clause divides these rows into groups according to the specified column(s).- The
HAVING
clause excludes groups not meeting its search conditions.- Any aggregate function specified in the select list performs its calculations for each group.
The following statement finds the customers that are frequent renters for the month:
SELECT cust_id FROM rentals
WHERE rental_date
BETWEEN '1993/10/01 00:00:00' AND '1993/10/31 23:59:59'
GROUP BY cust_id
HAVING COUNT (*) > 4;
Aggregate Functions, GROUP BY Clause, SELECT Statement, WHERE Clause
Add information to a database table
INSERT INTOtable-name
[(column-list
)] VALUES (literal | NULL [ , ... ])
INSERT INTOtable-name
[(column-list
)]query-expression
table-name
- Unique identifier for the database table.
column-list
- Columns which will have values inserted. See the description below.
VALUES
- Columns which will have values inserted. See the description below.
query-expression
- Subquery used to specify data to be inserted.
The
INSERT
statement enters information into the specified table. There are two forms of theINSERT
statement. In the first form, you insert a single row by specifying values for the specified columns. In the second form, you use a query to select rows from other tables to be inserted into the specified table.Within the first form of the
INSERT
statement, several format variations exist. The simplest format includes aVALUES
clause without a column list. In this format, you must provide a value for each column in the table. The values are listed in the same order that was used to create the columns in the database table.INSERT INTO roles
VALUES (72, 144, 'Margaret Schlegel');In a
VALUES
clause, the column values are separated by commas. You can enter character strings, date strings, and numeric constants as column values. If you are entering the data using JISQL, character strings and date values must be enclosed with single quotation marks.Inserting Rows Using a Column List
If you do not know the column order or if you do not want to enter a value for each column, you can add a column list to the statement:
INSERT INTO roles (title_id, actor_id, role)
VALUES (72, 144, 'Margaret Schlegel');With this format, the first column value, 72, is entered into the first column found in the column list,
title_id
. The second value goes into the second column listed, etc.If you do not specify a value for a column, its value will be set to
NULL
.Inserting Rows Containing a Null Value
You can also enter an unknown value for any column using
NULL
as the column value:INSERT INTO roles (title_id, actor_id, role)
VALUES (72, 144, NULL);However, this syntax is not available if the column was specified as
NOT NULL
in the CREATE TABLE Statement.Inserting Rows Using a Subquery
The second syntax statement illustrates the insertion of rows using a subquery. Multiple rows can be inserted with this format; however, you cannot have the same table named in the
INTO
clause and theSELECT
statement of the query.INSERT INTO roles
(title_id)
SELECT title_id FROM titles WHERE title_id > 75;
Specify the interconnection between two tables
... FROMtable-name
,table-name
WHEREtable-name
.column-name
join-operator
[ {AND|OR|NOT}
table-name.column-nametable-name
.column-name
join-operator
.
table-namecolumn-name
... ]
FROM
- The
FROM
clause lists the tables included in the join.table-name
- Identifier for the database table.
WHERE
- The
WHERE
clause specifies the relationship between each set of tables in addition to the search conditions to be used for the statement.column-name
- Column from one of the specified database tables.
join-operator
- One of the following operators: =, >, <, >=, <=, or <>.
A join connects two or more database tables by specifying the relationship between each set of tables. To specify the relationship, you connect one column from one table to a column in another table. The column names must be qualified with the table name if the table location is ambiguous. A join can be part of a
SELECT
,UPDATE
,INSERT
, orDELETE
statement. A join can also be included in a subquery. There are several types of joins which will be discussed in the following paragraphs.Equi-joins
An equi-join is based on equality as indicated by the equal sign (=). In an
equi-join
, all the columns in the tables being joined are included in the result set. For example,SELECT * FROM roles, actors
WHERE roles.actor_id = actors.actor_id;This statement joins the actors and roles tables using the
actor_id
column in each table. The result set lists the actor for each role included in the roles table.
Natural Joins
A natural join is structured so that there is no duplication of data. The same query as a natural join would appear as follows:
SELECT title_id, roles.actor_id, first_name, last_name, role
FROM roles, actors
WHERE roles.actor_id = actors.actor_id;The select list names the columns to be included so that the
actor_id
is displayed only once.
Multiple Table Joins
A multiple table join involves more than two tables using one or more columns to make the connection. The following statement adds the name of the video to the result set.
SELECT roles.title_id, titles.name, actors.actor_id,
actors.first_name, actors.last_name, roles.role
FROM roles, titles, actors
WHERE roles.title_id = titles.title_id
AND roles.actor_id = actors.actor_id;
You could also use correlation names to formulate the query:
SELECT r.title_id, t.name, a.actor_id,
a.first_name, a.last_name, r.role
FROM roles r, titles t, actors a
WHERE r.title_id = t.title_id
AND r.actor_id = a.actor_id;Additional search conditions can be added to the
WHERE
clause to further restrict the result set:SELECT roles.title_id, titles.name, actors.actor_id,
actors.first_name, actors.last_name, roles.role
FROM roles, titles, actors
WHERE roles.title_id = titles.title_id
AND roles.actor_id = actors.actor_id
AND titles.title_id = 19;
Non equi-joins
In addition to the equal sign, there are additional operators that can be specified. Table 6-2 lists all the relational operators that can be used in joins.
Table 6-2 Join operators
Operator Description =
Equal to
>
Greater than
<
Less than
>=
Greater than or equal to
<=
Less than or equal to
<>
Not equal to
You can also use a
BETWEEN
predicate to specify a range of values.The following query lists the videos that have the same name but have been directed by different people:
SELECT t.title_id, t.name, t.dir_last_name
FROM titles t, titles d
WHERE t.name = d.name
AND t.dir_last_name <> d.dir_last_name;
Self-joins
The previous query is called a self-join which joins a table to itself so that you can compare values in the same column. To make a self-join, use correlation names for the database tables in the
FROM
clause and in the column names.The following self-join finds the directors who have made two different types of films–for example, directors who have made both comedy and adventure films. All of this information is in the titles table. For this query, the join condition is made on the director's last name. Then, the two
genre_code
entries in each join are compared, and if they differ, the director's last name, the genre code and the name of each corresponding video are written to the result set.SELECT dir.dir_last_name, dir.genre_code, dir.name
FROM titles gen, titles dir
WHERE gen.dir_last_name = dir.dir_last_name
AND gen.genre_code <> dir.genre_code
The following self-join finds the actors in video #50 who are entered in the roles table only for that video. It uses one version of the roles table to find all the
actor_id
codes in video #50. It uses the other version of the table to find theactor_id
codes that are entered in the roles table only once.SELECT r.actor_id FROM roles r, roles j
WHERE r.title_id = 50
AND r.actor_id = j.actor_id
GROUP BY r.actor_id HAVING COUNT(j.actor_id) = 1;
Obtain data matching a specified pattern
column-name
[NOT] LIKEliteral
[ESCAPEliteral
]
column-name
- Column whose value you want to specify.
literal
- Wildcard characters intermixed with portions of column values.
A
LIKE
predicate selects rows in which a column value matches a specified pat tern. You can enter values for character strings or date strings. You can also enter a wildcard character to substitute for a portion of the string. Table 6-3 lists the wild card characters that can be used in JDB.
Table 6-3 Wildcard characters
Wildcard Description % (percent sign)
Substitutes for any string of zero or more characters
_ (underline)
Substitutes for any single character
With the specification of an
ESCAPE
clause, the special meaning given to "_" and "%" can be disabled.NOT LIKE
selects rows that do not match the specified pattern.
This query finds all the videos released in 1989:
SELECT title_id, name FROM titles
WHERE release_date LIKE '1989%';
The following example returns rows where the
dscr_text
begins with an underscore. The backslash removes the special meaning for the underscore, but not for the percent sign:SELECT * FROM title_dscr
WHERE dscr_text LIKE '\_%' ESCAPE `\';
Specify an unknown value
InINSERT
statements
... VALUES {literal
| NULL} [ , {literal
| NULL} ]InSELECT
statements,
... WHEREcolumn-name
IS [NOT] NULLInUPDATE
statements
... SETcolumn-name
= {literal
| NULL}
... [ ,column-name
= {literal
| NULL} ]
When a column is set to
NULL
, it specifies an unknown or an unspecified value. ANULL
value is not the same as a blank or a zero entered into a column.If you are using a comparison operator, be aware that
NULL
is not a value and therefore cannot be compared to any other value. As an example, the followingWHERE
clause would evaluate to true for all values of thetimes_rented
column that are greater than 75, but would evaluate to false if the column is set toNULL
.WHERE times_rented > 75
The examples illustrate the uses of
NULL
values in different types of statements.The following statement inserts a null value into the role column:
INSERT INTO roles (title_id, actor_id, role)
VALUES (16, 276, NULL);An error occurs if you attempt to insert a null value into a column which was created as
NOT NULL
. The following statement returns the errorNULL
not allowed since the columnactor_id
was specified asNOT NULL
in theCREATE TABLE
statement for the roles table.INSERT INTO roles (title_id, actor_id, role)
VALUES (27, NULL, 'Aunt Gussie');The following statement selects rows where the
rating_code
column contains a null value:SELECT name FROM titles WHERE rating_code IS NULL;
The following statement updates the
rental_comment
column to a null value for every row in the rentals table:UPDATE rentals SET rental_comment = NULL;The following statement updates the
rental_comment
to a null value for a specific rental:UPDATE rentals SET rental_comment = NULL
WHERE cust_id = 6
AND title_id = 69
AND copy_num = 2
AND rental_date = '1993/10/29 18:00:00';In order to obtain a unique entry for the rentals table, you must include an entry for the
cust_id
,title_id
,copy_num
andrental_date
columns.
This section describes the various operators available in JDB.
Arithmetic Operators
Arithmetic operators allow you to perform calculations on data in the database without altering the data. They are available to use with any numeric column. If the value in the column is
NULL
, the result will also beNULL
.Table 6-4 lists the arithmetic operators that are available in JDB.
Table 6-4 Arithmetic operators
Operator Definition +
Addition
-
Subtraction
*
Multiplication
/
Division
The arithmetic operators adhere to the following order of precedence:
Among operators that have the same level of precedence, the order of execution is from left to right. The order of precedence can also be explicitly specified using parentheses. For more information, refer to the section on logical operators.
The following statement uses an arithmetic operator to calculate the price with sales tax on an item:
SELECT pricecat, price * 1.0825 FROM pricecats
WHERE pricecat = 'N';Arithmetic operators can also be used in calculations that perform comparisons. The following statement finds rentals where the amount paid was greater than double the rental fee:
SELECT cust_id, title_id, rental_date FROM rentals
WHERE amount_paid > price * 2;Comparison Operators
Comparison operators allow you to compare one expression with another expression, where an expression is defined as a column name, a constant, a function, or any combination of column names, constants and functions.
Table 6-5 lists the comparison operators that are available in JDB.
Table 6-5 Comparison operators
Operator Definition =
Equal to
>
Greater than
<
Less than
>=
Greater than or equal to
<=
Less than or equal to
<>
Not equal to
When character or date strings are used in comparisons, they need to be enclosed in single quotation marks. Also, in these comparisons, numbers are greater than uppercase letters, and uppercase letters are greater than lowercase letters. For character strings, > asks for character strings closer to the end of the alphabet, < for character strings closer to the beginning of the alphabet. For date strings, > asks for dates later than the one specified and < asks for dates earlier than the one specified.
The following query asks for the videos whose length is greater than three hours:
SELECT title_id, name FROM titles WHERE film_minutes > 180
The following query lists the customers who joined during the current year:
SELECT cust_id, first_name, last_name FROM customers
WHERE member_date >= '1993/01/01 00:00:00';
Querying for a specific range of values can be accomplished using a series of comparison operators or a
BETWEEN
predicate. The following statements would return the same data:SELECT title_id, name FROM titles
WHERE film_minutes BETWEEN 150 AND 180;SELECT title_id, name FROM titles
WHERE film_minutes >=150 AND film_minutes <= 180;
Logical Operators
Logical operators join sets of search conditions together.
Table 6-6 lists the logical operators that are available in JDB.
Table 6-6 Logical operators
Operator Definition
AND
Joins two conditions and returns results when both conditions are true.
OR
Joins two conditions and returns results when either condition is true.
AND
operators take precedence overOR
operators unless you change the order of execution by using parentheses. Also,NOT
takes precedence overAND
.If you wanted to find the science fiction videos that either have a PG or G rating or that are over three hours long, the following query would not return the correct results. This query first finds the science fiction videos that have a PG or G rating. Then, it finds any videos over three hours long.
SELECT title_id, name, film_minutes FROM titles
WHERE genre_code = 'SCFI'
AND rating_code IN ('G', 'PG')
OR film_minutes > 180;
The addition of parentheses finds science fiction videos that either have a PG or G rating or that are over three hours long.
SELECT title_id, name, film_minutes FROM titles
WHERE genre_code = 'SCFI'
AND (rating_code IN ('G', 'PG')
OR film_minutes > 180);
Remember that if a column is set to
NULL
, no comparison operator will retrieve it. The value of null is unknown. The following example would find the video titles whose length is less than an hour but would not find the ones whose length is entered asNULL
:SELECT title_id, name FROM titles
WHERE film_minutes < 60;
Specify the order for the query results
ORDER BY {integer
| [correlation-name
.]column-name
} [ , ... ]
[ASC | DESC]
integer
- If integer is specified instead of a column-name, it refers to the position of a column or expression in the select list.
correlation-name
- Identifier which substitutes for the table name.
column-name
- Specifies the column or columns to be used for sorting the result set.
ASC
- Specifies that the result set is to be sorted in ascending order. This is the default.
DESC
- Specifies that the result set is to be sorted in descending order.
An
ORDER BY
clause sorts the result set according to the specified column or columns. The columns specified in theORDER BY
clause must also be specified in the select list of theSELECT
statement. By default, the sort occurs in ascending order which lists the smallest value first. You can set the sort order by specifyingASC
for ascending orDESC
for descending order.If you list more than one column in the
ORDER BY
clause, it creates a nested sort. The sort for the first column takes precedence and occurs first. Then, within each of these groups, the rows are sorted again according to the value of the second column.Instead of listing column names in the
ORDER BY
clause, you can use integers to refer to the column position.
The following
SELECT
statement without anORDER BY
clause returns the list of video titles in the order shown in the result set:SELECT title_id, name, genre_code FROM titles;
With the addition of an
ORDER BY
clause on the genre code, followed by the video name, the statement returns the data in the following order:SELECT title_id, name, genre_code FROM titles
ORDER BY genre_code, name;
If you use integers in the
ORDER BY
clause to refer to the column position, the previous statement appears in the following syntax:SELECT title_id, name, genre_code FROM titles
ORDER BY 3, 2;
genre_code
is the third column appearing in the select list, and name is the second column in the select list.
Obtain information from a database table
SELECT [DISTINCT] {select-list
| *} FROMtable-name
[correlation-name] [, ...]
[WHEREsearch-conditions
]
[GROUP BY [correlation-name
.]column-name
[, ...]]
[HAVINGsearch-conditions
]
[ORDER BY {integer
| [correlation-name
.]column-name
} [, ...]]
DISTINCT
- Exclude any duplicate rows from the result set.
select-list
- A series of column names, qualified by the table name if more than one database table is being accessed, and/or aggregate functions.
*
- Selects every column from every table listed in the
FROM
clause.table-name
- Identifier for a database table.
correlation-name
- Identifier which substitutes for the table name in the remainder of the statement.
WHERE
- The
WHERE
clause specifies a search condition or a join. For more information on joins, refer to page 6-27. For more information on theWHERE
clause, refer to page 6-54.search-conditions
- Specifies the conditions for the selection of data. For more information, refer to page 6-54.
GROUP BY
- The
GROUP BY
clause specifies the column used to divide the result set into groups. For more information, refer to page 6-21.HAVING
- The
HAVING
clause specifies a search condition. For more information, refer to page 6-23ORDER BY
- The
ORDER BY
clause specifies the column(s) used to sort the result set. For more information, refer to page 6-42.
The SELECT statement obtains data from the specified database table or tables. In its simplest form, the SELECT statement retrieves all the data from all the columns in the named table:
SELECT * FROM titles;
However, this syntax is not recommended for use inside an application. It is recommended that you include a select list in a
SELECT
statement.Specifying a Select List
A select list determines which columns will be included in the result set. In the following example, the select list contains the name,
genre_code
,dir_last_name
andfilm_minutes
columns:SELECT name, genre_code, dir_last_name, film_minutes
FROM titles;
The select list can also include aggregate functions.
SELECT AVG (film_minutes) FROM titles;
Specifying a WHERE Clause
You can choose which rows will be a part of the result set by including a
WHERE
clause:SELECT name, genre_code, dir_last_name, film_minutes
FROM titles WHERE dir_last_name = 'Weir';
There are other search conditions available. Refer to page 6-54 for information on the
WHERE
clause.Obtaining Unique Entries
You can include only unique rows in the result set by specifying the keyword
DISTINCT
. The following statement gets a list of directors:SELECT dir_last_name FROM titles;
By using
DISTINCT
, the duplicate names are excluded from the result set:SELECT DISTINCT dir_last_name FROM titles;
Obtaining Data from Multiple Tables
You can obtain information from more than one database table by using joins:
SELECT name, first_name, last_name, role
FROM actors, titles, roles
WHERE titles.title_id = roles.title_id
AND actors.actor_id = roles.actor_id;
Refer to page 6-27 for more information on joins.
BETWEEN Predicate, Joins, GROUP BY Clause, HAVING Clause, Subqueries, WHERE Clause
Nest a SELECT statement within another statement
In a subquery, you can nest a
SELECT
statement within aSELECT
,INSERT
,UPDATE
, orDELETE
statement. The main syntax restriction is that a subquery cannot contain anORDER BY
clause. Refer to the sections on each keyword for any additional syntax restrictions. The subquery is enclosed in parentheses. Many statements using subqueries can alternatively be constructed using joins.There are five keywords used for subqueries:
EXISTS
,IN
,ANY
,ALL
, andSOME
. These are explained below.
EXISTS
WHERE [NOT] EXISTS (subquery)
The
EXISTS
keyword tests for the presence of a result set from the subquery. The subquery can contain one or more columns. Since you are testing to see if any rows are returned, you can useSELECT
* instead of a select list in the subquery.If the
NOT
keyword is also specified, theWHERE
clause is satisfied if there are no rows in the result set.The following query checks to see if all of the video titles have entries in the roles table:
SELECT title_id FROM titles WHERE NOT EXISTS
(SELECT * FROM roles
WHERE roles.title_id = titles.title_id);
IN
WHERE expression [NOT] IN (subquery)
The
IN
subquery condition evaluates whether the expression in theWHERE
clause matches any row returned in the subquery. The subquery usingIN
can only return one column, but it can return more than one row.A subquery using the keyword IN is equivalent to the same subquery using =ANY.
The following query lists which science fiction movies a customer has previously rented:
SELECT title_id, name FROM titles WHERE genre_code = 'SCFI'
AND title_id IN
(SELECT title_id FROM rentals
WHERE cust_id = 6);
ANY
,ALL
,SOME
WHERE
expression comparison-operatorANY
(subquery)WHERE
expression comparison-operatorALL
(subquery)WHERE
expression comparison-operatorSOME
(subquery)The keywords
ANY
,ALL
, orSOME
are used with a subquery with one of the following comparison operators: >, >=, <, <=, <>, or =.A subquery using
ANY
orSOME
tests to see if the comparison is true for at least one of the values returned by the subquery. If the subquery returns no value, the search condition is false.SELECT title_id, name FROM titles WHERE title_id = ANY
(SELECT title_id FROM tapes WHERE status = 'I');
A subquery using
ALL
tests to see if the comparison is true for every value returned by the subquery. If the subquery returns no value, the search condition is true as well.The following query tests to see which actors are not in the roles table:
SELECT actor_id, first_name, last_name FROM actors
WHERE actor_id <> ALL
(SELECT actor_id FROM roles);
The keywords
ANY
,ALL
, orSOME
can be omitted if you know that the subquery will return exactly one value. The following example returns one value by using an aggregate function. This query finds the customers whose rental amount was higher than average:SELECT cust_id, first_name, last_name FROM customers
WHERE rent_amount >
(SELECT AVG(rent_amount) FROM customers);
Nested Subqueries
A subquery can also contain another subquery.
The following query finds the videos depicting dramatic stories that are also in the rentals table:
SELECT title_id, name FROM titles WHERE title_id IN
(SELECT title_id FROM rentals WHERE title_id IN
(SELECT title_id FROM titles WHERE genre_code = 'DRAM'));
Update information in a database table
UPDATEtable-name
SETcolumn-name
= value [, ...]
[WHEREsearch-conditions
]
table-name
- Unique identifier for the database table.
SET
- The
SET
clause lists both the columns to be updated and the new values for those columns.column-name
- Name of the column to be modified.
WHERE
- The
WHERE
clause specifies which rows will be updated. Refer to page 6-54 for more information on theWHERE
clause.search-conditions
- Specifies the conditions for the selection of data. For more information, refer to page 6-54.
The
UPDATE
statement modifies the value of one or more columns in the specified table.If the
UPDATE
statement is part of a transaction, the update can be undone by rolling back the transaction.Warning: If you omit the
WHERE
clause, all rows in the table are updated.
The following statement increases each price category by 10%. Since there is no
WHERE
clause, this statement updates each row in the pricecats table:UPDATE pricecats SET price = price * 1.1;The following statement updates the price category for a video:
UPDATE titles SET pricecat = 'G' WHERE title_id = 57;The following query updates the member status to the frequent renter category if a customer rents over 10 videos a month:
UPDATE customers SET member_status = 'F'
WHERE cust_id IN
(SELECT cust_id FROM rentals
WHERE rental_date
BETWEEN '1993/09/01 00:00:00' AND '1993/10/01 00:00:00'
GROUP BY cust_id HAVING COUNT(*) > 10 ');
Specify search conditions and/or specify the relationship between tables
WHEREsearch-conditions
WHEREcolumn-name
join-operator
column-name
search-conditions
- Specifies the conditions for the selection of data.
column-name
- Specifies a column in each of the tables to be joined.
join-operator
- Specifies the join operator. Refer to page 6-27 for more information about joins.
The
WHERE
clause performs two functions:
- Specifying the search conditions for the result set.
- Specifying the connection between tables named in the
FROM
clause.
Search conditions can include the following:
BETWEEN
WHERE [NOT] expression [NOT] BETWEEN expression AND expression
- The
BETWEEN
predicate specifies a range of database values. The following statement returns all the customers who joined during a certain year:SELECT cust_id, first_name, last_name FROM customers
WHERE member_date BETWEEN '1992/01/01 00:00:00'
AND '1993/01/01 00:00:00';
EXISTS
WHERE [NOT] EXISTS subquery
- The
EXISTS
keyword tests for the presence of a result set from the subquery. If theNOT
keyword is also specified, theWHERE
clause is satisfied if there are no rows in the result set. The subquery is enclosed in parentheses.- Notice that the subquery uses an * instead of a select list since you are merely testing whether rows meet the subconditions specified in the query.
SELECT title_id, name FROM titles WHERE EXISTS
(SELECT * FROM tapes WHERE title_id = tapes.title_id
AND status = 'I');
IN
WHERE expression [NOT] IN subquery
t
WHERE expression [NOT] IN values-lis- The
IN
keyword evaluates whether or not the expression in theWHERE
clause matches a row in the subquery or a value in the values list. The subquery usingIN
can only return one column, but it can return more than one row.- The following query uses a values list to find the adventure and science fiction videos. It tests whether the
genre_code
for each video matchesADV
orSCFI
.SELECT name, rating_code FROM titles
WHERE genre_code IN ('ADV', 'SCFI');
IS NULL
WHERE column-name IS [NOT] NULL
- The keyword
IS NULL
searches for null values in the specified column.SELECT name FROM titles WHERE rating_code IS NULL;
LIKE
WHERE column-name [NOT] LIKE literal [ESCAPE literal]
- A
LIKE
predicate selects rows where a column value matches a specified pattern. The following query finds the video titles that begin with "M."SELECT title_id, name FROM titles WHERE name LIKE 'M%'
- Operators
WHERE expression {> | < | >= | <= | = | <>}{expression | subquery}
- Operators allow you to compare column values. The following query finds the customers who have rented more than 2000 videos. For more information on using operators in subqueries, refer to page 6-48.
SELECT cust_id, first_name, last_name FROM customers
WHERE num_rentals > 200;
Specifying Joins
The
WHERE
clause also specifies the interconnecting columns between tables in joins. The following statement illustrates a multiple join. For additional information on joins, refer to page 6-27.SELECT name, first_name, last_name, role
FROM titles, actors, roles
WHERE titles.title_id = roles.title_id
AND roles.actor_id = actors.actor_id
AND titles.title_id = 62;
BETWEEN Predicate, Joins, LIKE Predicate, Null Values, Operators, Subqueries
CREATE DATABASEdatabase-name
CREATE TABLEtable-name
(
column-name
data-type
[(length
)] [NOT NULL] [,column-name
...]
[PRIMARY KEY (column-name
,column-name
...]), ]
[UNIQUE (column-name
[,column-name
...]), ]
[FOREIGN KEY (column-name
[,column-name
...])
REFERENCEStable-name
(column-name
[,column-name
...]) [,]
]CREATE TABLEtable-name
(
column1
data-type
[(length
)] NOT NULL,
column2
data-type
[(length
)] NOT NULL,
column3
data-type
[(length
)] NOT NULL,
column4
data-type
[(length
)] NOT NULL,
column5
data-type
[(length
)],
column6
data-type
[{length
)],
PRIMARY KEY (column1
,column2
),
UNIQUE (column2
),
UNIQUE (column3
,column4
),
FOREIGN KEY (column5
,column6
)
REFERENCEStable2
(column
,column
),
FOREIGN KEY (column5
) REFERENCEStable3
(column
)
)DELETE FROMtable-name
[WHEREsearch-conditions
]DROP DATABASEdatabase-name
DROP TABLEtable-name
INSERT INTOtable-name
[(column-list
)]
VALUES (literal| NULL [, ...])INSERT INTOtable-name
[column-name
[, ...]]query-expression
SELECT [DISTINCT] {select-list
| *}
FROMtable-name
[correlation-name
] [, ...]
[WHEREsearch-conditions
]
[GROUP BY [correlation-name
.]column-name
[, ...]]
[HAVINGsearch-conditions
]
[ORDER BY {integer
| [correlation-name
.]column-name
} [, ...] ]UPDATEtable-name
SETcolumn-name
=value
[, ...]
[WHEREsearch-conditions
]