Sie sind auf Seite 1von 53

ALTER TABLE MIN

AVG ORDER BY
BETWEEN ... AND ... PARAMETERS
CONSTRAINT RIGHT JOIN
COUNT SELECT
CREATE INDEX SELECT INTO
CREATE TABLE SELECT SUBQUERY
DELETE STDEV
DROP STDEVP
FIRST SUM
GROUP BY TRANSFORM
HAVING UNION
INNER JOIN UPDATE
INSERT INTO VAR
LAST VARP
LEFT JOIN WHERE
LIKE WITH OWNERACCESS OPTION
MAX
ALTER TABLE
CREATE INDEX
CREATE TABLE
DELETE
DROP
INSERT INTO
SELECT
SELECT INTO
SELECT SUBQUERY
TRANSFORM
UPDATE
BETWEEN ... AND ...
INNER JOIN
LEFT JOIN
LIKE
RIGHT JOIN
UNION
AVG
COUNT
FIRST
LAST
MAX
MIN
STDEV
STDEVP
SUM
VAR
VARP
PARAMETERS
WITH OWNERACCESS OPTION
CONSTRAINT
GROUP BY
HAVING
ORDER BY
WHERE
Quick Reference Library

JetSQL Quick Reference

Copyright 1999-2002 by Infinite Software Solutions, Inc. All rights reserved.

Trademark Information.
Welcome to the DevGuru Jet SQL Quick Reference guide. This is an informative 40 page
reference source that explains and gives examples of code for the clauses, declarations,
expressions, functions, operators, and statements used by Jet SQL.

The Structured Query Language (SQL) is a computer language for accessing and
manipulating databases. The fundamental concept is to think of the data as being stored in
one or more tables. When a request is made to retrieve data from these tables, which is
called a "query", the resultant output is also presented in as table. There are many different
versions of the SQL language, but to be in compliance with the ANSI SQL '92 Standard, they
must use and support the same major keywords in a similar manner (such as SELECT,
UPDATE, DELETE, INSERT, WHERE, and others).

The version of SQL created by Microsoft is called Jet SQL and it is the database engine
behind Microsoft's Access.

Jet SQL has certain limitations compared to the other versions of SQL. In general, Jet SQL
is not designed to manage a database, but rather, it is used to retrieve information from a
database. To cite two limitations, Jet SQL, by itself, cannot create a database and cannot
manage security . This is where the Microsoft Data Access Object, commonly called DAO,
enters the scene. DAO contains libraries which are designed to manage databases. While,
yes, you can use Jet SQL without DAO, you are effectively limiting your options to handle
the data. For example, with DAO you can create a database and manage security. Likewise,
Microsoft's Access offers the ability to create and maintain databases.

The value of Jet SQL (and DAO) is that it allows the developer to add databases to an active
Web site.
STATEMENT: ALTER TABLE
ALTER TABLE table
{ADD {COLUMN field type[(size)] [NOT NULL] [CONSTRAINT index] |
CONSTRAINT multifieldindex} |
DROP {COLUMN field | CONSTRAINT indexname} }

The ALTER TABLE statement can be used to alter an existing table by adding or dropping
columns and indexes.

You can use ADD COLUMN to add a single field to a table by specifying the field name, data
type and, optionally, a size for the Text and Binary fields:

ALTER TABLE Sales ADD COLUMN UnitPrice CURRENCY;

You can add the reserved words NOT NULL to require valid data to be added to that field:

ALTER TABLE Sales ADD COLUMN UnitPrice CURRENCY NOT NULL;

...and you can use DROP COLUMN to delete a single field :

ALTER TABLE Sales DROP COLUMN UnitPrice;

You can also define an index for a new field by using the CONSTRAINT clause:

ALTER TABLE Sales ADD COLUMN Item TEXT CONSTRAINT UniqueConstraint UNIQUE;

You can use ADD CONSTRAINT to add a multi-field index:

ALTER TABLE Names ADD CONSTRAINT UniqueValues UNIQUE (FirstName, LastName);

...and DROP CONSTRAINT to remove a multi-field index:

ALTER TABLE Names DROP CONSTRAINT UniqueValues;

Microsoft warns, "The Microsoft Jet database engine doesn't support the use of any DDL
statements with databases produced by any other database engine. Use the DAO (Data
Access Objects) Create methods instead."
FUNCTION: AVG
SELECT AVG(field) AS [expression]
FROM table
[WHERE ...]

The AVG function is one of the aggregate functions that are used to calculate statistical
information for a specified numeric field in a query. The other aggregate functions are: COUNT,
MAX, MIN, STDEV, STDEVP, SUM, VAR, VARP. Note that all of these functions return a
single value.

The AVG function simply calculates the arithmetic mean (i.e., the sum of the values divided by
the number of values). Values which are NULL are not included in the calculations. If the field
is just an empty set, no average will be calculated.

This code finds the average hospital stay of those MediCare patients over the age of 65:

SELECT AVG(DaysInHospital) AS [AverageStay]


FROM MediCarePatients
WHERE age > 65
OPERATION: BETWEEN ... AND
SELECT * | list FROM table
WHERE expression [NOT] BETWEEN value1 AND value2

The BETWEEN ... AND operator is used to specify a selection criteria by requiring an
expression to be equal to one of, or fall between the range defined by, two values. These
values can be numbers, characters, strings, or dates, but you cannot use any wildcard
characters. The characters, strings, and dates must be enclosed by a pair of single quotes.

In this query, we search for song titles released during the 1980s:

SELECT * FROM SongTitles


WHERE ReleaseDate BETWEEN #1/1/80# AND #12/31/89#

By using the NOT operator, you can search for values that lie outside the range:

SELECT * FROM Instruments


WHERE CatNum NOT BETWEEN 1097 AND 2355
CLAUSE: CONSTRAINT
Single-field constraint:

CONSTRAINT name {PRIMARY KEY | UNIQUE | NOT NULL |


REFERENCES foreigntable [(foreignfield1, foreignfield2)]}

Multiple-field constraint:

CONSTRAINT name
{PRIMARY KEY (primary1[, primary2 [, ...]]) |
UNIQUE (unique1[, unique2 [, ...]]) |
NOT NULL (notnull1[, notnull2 [, ...]]) |
FOREIGN KEY (ref1[, ref2 [, ...]])
REFERENCES foreigntable [(foreignfield1 [, foreignfield2 [, ...]])]}

The CONSTRAINT clause is used to maintain data integrity by providing limits on the values
that can be inserted into a column or table. While a CONSTRAINT clause is somewhat similar
to an INDEX, a CONSTRAINT can establish a relationship with another table. To place a
constraint on a single field in a CREATE TABLE or ALTER TABLE statement, follow the
definition of that field with a CONSTRAINT clause. This consists of a name for the constraint
and one of the following reserved words: PRIMARY KEY, UNIQUE, NOT NULL or
REFERENCES.

The PRIMARY KEY reserved word designates a field (or set of fields) as a primary key. It is
mandatory that all values in the primary key must be unique and not NULL. The following
example sets the NameID field to be the primary key of the Names table:

CREATE TABLE Names (NameID INTEGER CONSTRAINT NameIDKey PRIMARY KEY,


FirstName TEXT (20), LastName TEXT (20), DateOfBirth DATETIME);

An error will occur if you try to use a PRIMARY KEY constraint on a table that already has a
primary key.

The reserved word UNIQUE requires that the value entered into the specified field (or
combination of fields) be unique, as in the following example which only allows unique first
names:

CREATE TABLE Names (NameID INTEGER, FirstName TEXT (20) CONSTRAINT


UniqueName UNIQUE, LastName TEXT (20), DateOfBirth DATETIME);

You can use the reserved word NOT NULL to specify that a fields in a table must always
contain valid data (and cannot contain NULL):

CREATE TABLE Names (NameID INTEGER, FirstName TEXT (20) NOT NULL, LastName
TEXT (20) NOT NULL, DateOfBirth DATETIME NOT NULL)

You can establish a relationship with a field in a foreign table (as long as it only contains
unique values) by using the reserved word REFERENCES and naming that foreign table and
the field:

CREATE TABLE Sales (SalesID INTEGER, ProductID INTEGER, Item TEXT CONSTRAINT
ForeignRefs REFERENCES Products (Item) );
...or if the field in the foreign table is the primary key, you only need name the table and the
database engine references it by default:

CREATE TABLE Sales (SalesID INTEGER, ProductID INTEGER CONSTRAINT


ForeignKeyRef REFERENCES Products, Item TEXT);

When you want to apply a constraint to more than one field (a multiple-field constraint), you
can do so by adding the CONSTRAINT clause after all the field definitions. The next example
makes the two fields FirstName and LastName a joint primary key:

CREATE TABLE Names (NameID INTEGER, FirstName TEXT (20), LastName TEXT (20),
DateOfBirth DATETIME,
CONSTRAINT NameKey PRIMARY KEY(FirstName, LastName) );

...whereas this next one requires the combination of FirstName, LastName and DateOfBirth to
be unique:

CREATE TABLE Names (NameID INTEGER, FirstName TEXT (20), LastName TEXT (20),
DateOfBirth DATETIME,
CONSTRAINT UniqueFields UNIQUE(FirstName, LastName, DateOfBirth) );

Note that it is acceptable for one or more of the fields in a multiple-field constraint to contain
values that are the same, as long as the combination of values in all the constrained fields is
unique.

If you want to include a FOREIGN KEY that consists of more than one field, you must use a
multiple-field constraint definition. The constraint definition must list the names of the
referencing fields, the foreign table and the referenced fields in the foreign table. The order of
the referenced fields must correspond to the order of the refering fields:

CREATE TABLE Albums (AlbumID INTEGER, AlbumName TEXT, TuneName TEXT,


TuneType TEXT,
CONSTRAINT ReferForeignField FOREIGN KEY(TuneName, TuneType) REFERENCES
Tunes (Name, Type) );

Microsoft warns, "The Microsoft Jet database engine doesn't support the use of any DDL
statements with databases produced by any other database engine. Use the DAO (Data
Access Objects) Create methods instead."
FUNCTION: COUNT
SELECT COUNT(field) AS [expression]
FROM table
[WHERE ...]
[GROUPBY ...]
[HAVING ...]

The COUNT function is one of the aggregate functions that are used to calculate statistical
information for a specified numeric field in a query. The other aggregate functions are: AVG,
MAX, MIN, STDEV, STDEVP, SUM, VAR, VARP. Note that all of these functions return a
single value.

The COUNT function simply counts how many values are in a field. Values which are NULL
are included in the counting. If the field is just an empty set, COUNT returns zero.

This code finds the number of MediCare patients that were in the hospital on June 30, 1999
and stores that number into PatientCount. Note that the date format in Jet SQL is:
#mm/dd/yyyy#

SELECT COUNT(Patients) AS [PatientCount]


FROM MediCarePatients
WHERE Date = #06/26/2000#
STATEMENT: CREATE INDEX
CREATE [ UNIQUE ] INDEX index ON table (field [ASC|DESC][, field [ASC|DESC], ...])
[WITH { PRIMARY | DISALLOW NULL | IGNORE NULL }]

The CREATE INDEX statement is used to index one or more fields in an existing table. You
can do this by giving the index a name, and by stating the table and field(s) to which the index
will apply. The following example creates a simple index on the Name field of the Customer
table:

CREATE INDEX CustomerIndex ON Customers (Name);

By default, the values in a field are indexed in ascending order, but if you want to index them in
descending order, you can add the reserved word DESC. You can also index more than one
field simply by listing the fields within parentheses.

CREATE INDEX CustomerIndex ON Customers (Name DESC, City);

If you want to prohibit duplicate values in the indexed field or fields, you can use the reserved
word UNIQUE:

CREATE UNIQUE INDEX CustomerIndex ON Customers (Name);

The optional WITH clause allows you to enforce further data validation rules by using three
options:

With the DISALLOW NULL option you can prohibit NULL entries in the indexed field(s):

CREATE UNIQUE INDEX CustomerIndex ON Customers (Name)


WITH DISALLOW NULL;

With the IGNORE NULL option you can exclude records with NULL values in the indexed
field(s) from the index:

CREATE UNIQUE INDEX CustomerIndex ON Customers (Name)


WITH IGNORE NULL;

While the PRIMARY option allows you to designate which indexed field or fields to be the
primary key (since primary keys are always unique, there's no need to include the reserved
word UNIQUE):

CREATE INDEX CustomerIndex ON Customers (CustomerID)


WITH PRIMARY;

Note that you cannot use the reserved word PRIMARY to create an index on a table that
already has a primary key.

You can also use CREATE INDEX to create a pseudo index on a linked table in an ODBC data
source, such as SQL Server. Note however, that this will only work if the table does not already
have an index. You do not need permission or access to the remote server to create the
pseudo index, and the remote database will be unaware of and unaffected by the operation:

CREATE UNIQUE INDEX OrderIndex ON OrderDetailsODBC (OrderID);


Microsoft warns, "The Microsoft Jet database engine doesn't support the use of any DDL
statements with databases produced by any other database engine. Use the DAO (Data
Access Objects) Create methods instead."
STATEMENT: CREATE TABLE
CREATE TABLE table (field1 type [(size)] [NOT NULL] [index1]
[, field2 type [(size)] [NOT NULL] [index2] [, ...]]
[, CONSTRAINT multifieldindex [, ...]])

The CREATE TABLE statement is used to create a new table and its fields. At its simplest you
can create a table containing only a single field by specifying the name you want to give the
table, the field name and the type of data you want the field to contain:

CREATE TABLE Names (Name TEXT);

You can, of course, include more than one field, and also limit the size of those fields (Text and
Binary fields only) by stating the size in parentheses after the data type declaration:

CREATE TABLE Names (FirstName TEXT (20), LastName TEXT (20) );

If you require that a particular field must always have valid data entered into it, you can include
the expression NOT NULL at the end of the declaration for that field. If you do not enter the
required data, you will get a warning message:

CREATE TABLE Names (FirstName TEXT (20), LastName TEXT (20) NOT NULL);

More often than not, you'll want to place some sort of restriction on the data, or combinations of
data, that are entered into fields. You can do this by using the CONSTRAINT clause. The
following example expands on the previous ones by adding a Date of Birth field and requiring
that the combination of data in all three fields be unique:

CREATE TABLE Names (FirstName TEXT (20), LastName TEXT (20), DateOfBirth
DATETIME, CONSTRAINT MultiConstraint UNIQUE(FirstName, LastName, DateOfBirth) );

Microsoft warns, "The Microsoft Jet database engine doesn't support the use of any DDL
statements with databases produced by any other database engine. Use the DAO (Data
Access Objects) Create methods instead."
STATEMENT: DELETE
DELETE [table,*] FROM table WHERE criteria

The DELETE statement creates a query that removes records from one or more tables. You
can totally empty a table of all records while leaving the table structure and properties, such as
attributes and indexes, intact:

DELETE * FROM Residents;

...or you can be more specific and just delete those records that meet certain criteria:

DELETE * FROM Residents WHERE Occupation = 'Teacher';

You can use a "cascade delete" operation to remove records from tables that are in a one-to-
many relationship with other tables. A cascade delete causes the records in tables that are on
the many side of the relationship to be deleted when the corresponding record in the one side
of the relationship is deleted.

The Jet database engine will cascade delete if the relationships between tables are configured
to enable this option. While Jet SQL gives us a mechanism to establish a relationship (using
the CONSTRAINT clause) it does not give us any method to configure relationships to enable
cascading operations. However, if a relationship has been configured to enable cascading
operations, for example by using Microsoft Access or DAO (Data Access Objects), the Jet SQL
DELETE (and UPDATE) statements will cascade.

A DELETE is permanent!

After you remove records using a DELETE statement, you cannot undo the operation. To
check which records will be deleted, examine the results of a SELECT query that uses the
same criteria.

It is also important to understand, that a DELETE statement deletes entire records, not just
data in specified fields. If you just want to delete certain fields, use an UPDATE query that
changes the value to NULL.
STATEMENT: DROP
DROP {TABLE table | INDEX index ON table}

The DROP statement can be used to delete an existing index from a table...

DROP INDEX UniqueValues ON Names;

...or delete an entire table from a database:

DROP TABLE Names;

You must close a table before you use the DROP statement.
FUNCTION: FIRST
SELECT FIRST(field) AS [expression]
FROM table
[WHERE ...]
[GROUP BY ...]
[ORDER BY ...]

The FIRST function is used to return the value of the first record in the designated field
Therefore, this function returns a single value. Since the records are returned in an arbitrary
order, the first record will also be arbitrary. You can use the ORDER BY clause to order the
records.

The companion LAST function returns the last record in the designated field.

This code finds the first birthdate in a table of MediCare patients that is ordered by the age
field.

SELECT FIRST(birthdate) AS FirstBirthDate


FROM MediCarePatients
ORDER BY age
CLAUSE: GROUP BY
SELECT fieldlist FROM table WHERE criteria [GROUP BY groupfieldlist] [HAVING
search_criteria]

The optional GROUP BY clause combines into a single record all records that have identical
values in a particular field or combination of fields. You can use up to 10 fields to group
records, with the order of field names determining the group levels from highest to lowest. A
HAVING clause may also be used in conjunction with a GROUP-BY clause to further restrict
the search criteria. All fields containing a NULL are considered to have a value and will be
grouped along with the fields containing non-NULL values. The following example returns a list
of the different products in the Product field of Suppliers:

SELECT Product FROM Suppliers GROUP BY Product;

You can also use any of the nine aggregate functions (AVG, COUNT, MIN, MAX, STDEV,
STDEVP, SUM, VAR, VARP) to include statisical values for each record. Any field containing a
NULL value will be ignored in the statistical calculations performed by the aggregate functions.
Expanding on the previous example, the following returns a list of different products and a field
called ProdCount that counts the number of times each product occurs in the Product field of
Suppliers (i.e. how many suppliers supply it):

SELECT Product, COUNT(Product) AS ProdCount FROM Suppliers


GROUP BY Product;

You can also include a WHERE clause to apply certain criteria before values are grouped. The
next example returns a list of all different products that are blue, and the sum cost for one of
each:

SELECT Item, Sum(UnitPrice) AS TotalCost FROM Products


WHERE Color = 'blue'
GROUP BY Item;

If a field appears in the SELECT field list, it must appear in either the GROUP BY clause or as
an argument to one of the SQL aggregate functions.
CLAUSE: HAVING
SELECT fieldlist FROM table WHERE selectcriteria
GROUP BY groupfieldlist [HAVING groupcriteria]

The HAVING clause is optional and qualifies a GROUP BY clause. It is similar to the WHERE
clause, but HAVING establishes restrictions that determine which records are displayed after
they have been grouped. The following example displays a list of different items, along with
their count, but only where there are more than one:

SELECT Item, Count(Item) AS Tally FROM Products


GROUP BY Item HAVING Count(Item) > 1;

A HAVING clause can contain up to 40 expressions linked by logical operators such as AND
and OR:

SELECT Item, Count(Item) AS Tally, Max(UnitPrice) AS MaxPrice


FROM Products GROUP BY Item
HAVING Count(Item) > 1 AND Max(UnitPrice) < 40;

Note that the above example returns a list of items only where the whole group meets the
criteria of the HAVING clause, that is only items of which there are more than 1, and none of
which cost more than $40. If you wanted a count of only those items that cost less than $40
(there could be others that cost more) and which number more than 1, then you would have to
use the following query:

SELECT Item, Count(Item) AS Tally, Max(UnitPrice) AS MaxPrice


FROM Products WHERE UnitPrice < 40
GROUP BY Item HAVING Count(Item) > 1;
OPERATION: INNER JOIN
SELECT * | list FROM table1
INNER JOIN table2 ON table1.field1 compoperator table2.field2

The INNER JOIN operation can be used in any FROM clause to combine records from two
tables. It is, in fact, the most common type of join. There must be a matching value in a field
common to both tables.

An INNER JOIN cannot be nested inside a LEFT JOIN or RIGHT JOIN.

The following example returns a list of all employees who live in Boston and who are working
on the Hardwork project:

SELECT Employee.Username
FROM Employee INNER JOIN Project
ON Employee.EmployeeID = Project.EmployeeID
WHERE Employee.City = 'Boston'
AND Project.ProjectName = 'Hardwork';

Note that you can join any two numeric fields as long as they are of like type (such as
AutoNumber and Long). However, with non-numeric data, the fields must be of the same type
and contain the same kind of data, though they can have different names.

With the INNER JOIN operation any relational comparison operator can be used in the ON
clause: =, <, >, <=, >=, or <>. The following example returns all cases where the value in the
EmployeeID field of Employee matches that in the EmployeeID field of Project (i.e. it returns
the names of those employees working on each of the projects).

SELECT Employee.username, Project.ProjectName


FROM Employee INNER JOIN Project
ON Employee.EmployeeID = Project.EmployeeID;

...whereas this example returns all employees not working on each project:

SELECT Employee.Username, Project.ProjectName


FROM Employee INNER JOIN Project
ON Employee.EmployeeID <> Project.EmployeeID;

You can also link several clauses in a INNER JOIN statement: the following example returns
all employees working on each project who live in the same city as where the project is taking
place:

SELECT Employee.Username, Project.ProjectName, Project.Location


FROM Employee INNER JOIN Project
ON (Employee.EmployeeID = Project.EmployeeID)
AND (Employee.City = Project.Location);

And you can also nest statements as in the following example which returns all tunes recorded
by musicians who are members of duos:

SELECT Tunes.Name, Musicians.Name, Duos.Name


FROM Tunes INNER JOIN (Musicians INNER JOIN Duos
ON (Musicians.Name = Duos.Member1)
OR (Musicians.Name = Duos.Member2))
ON Tunes.Musician = Musicians.Name;

An inner join can also be achieved by using the WHERE clause. The following query returns
the same set of records as the previous example:

SELECT Tunes.Name, Musicians.Name, Duos.Name


FROM Tunes, Musicians, Duos
WHERE ((Musicians.Name = Duos.Member1)
OR (Musicians.Name = Duos.Member2))
AND (Tunes.Musician = Musicians.Name);

Microsoft warns, "If you try to join fields containing Memo or OLE Object data, an error will
occur."
STATEMENT: INSERT INTO
Single-record:

INSERT INTO target [(field1[, field2[, ...]])] VALUES (value1[, value2 [, ...])

Multiple-record:

INSERT INTO target [IN externaldatabase] [(field1[, field2[, ...]])]


SELECT [source.] field1[, field2[, ...] FROM tableexpression

To add a specific record to a table, the INSERT INTO statement is followed by the name of the
table and the names of the various fields. If you don't specify each field, a default value or
NULL will be inserted for missing columns. Each value in the VALUES clause is inserted into
the field that corresponds to the value's position in the list: the first value is inserted into field 1,
the second into field 2 etc.

INSERT INTO Musicians ( Name, Instrument )


VALUES ('Bobby Lee', 'fiddle');

Note that if you omit the field list, you must include a value for every field in the table, otherwise
the operation will fail. The values must also be seperated by commas, and text fields enclosed
in single quotation marks (' ').

When using the multiple-record syntax the INSERT INTO statement precedes a SELECT
statement and adds a single or multiple records to a table. This is referred to as an append
query, as it copies records from one or more tables to another. The tables that contain the
records being appended are not affected by the operation:

INSERT INTO Duos ( Member1 )


SELECT Name FROM Musicians;

An AutoNumber field (also refered to as a Counter field) is a data type that automatically
creates and stores a number for each item added to a table. If you append records to a table
with an AutoNumber field and you do not want the AutoNumbered field to be renumbered, you
must include the AutoNumber field number in the query. If you do not include the AutoNumber
field, the appended items will be assigned a new AutoNumber field value.

If the destination table contains a PRIMARY KEY, you can only append unique non-NULL
values to the PRIMARY KEY field.

The following example would append to the Dous table, only those records that had a unique
primary key:

INSERT INTO Duos ( Member1 )


SELECT Name FROM Musicians
WHERE MusicianID > 3;

You can also append records to a table in another database using the IN clause:

INSERT INTO Residents (Name, Occupation) IN Residents.mdb


SELECT Name, Occupation FROM Immigration
WHERE Residency = 'granted';
As with a straight-forward SELECT statement, the FROM clause may include more than one
table linked by a JOIN operation. This is illustrated in the following example which appends to
the 'Insurance' table the names of all those employees involved in the 'Hardwork' project:

INSERT INTO Insurance (Name)


SELECT Employee.Username FROM Employee INNER JOIN Project
ON Employee.EmployeeID = Project.EmployeeID
WHERE Project.ProjectName = 'Hardwork';
FUNCTION: LAST
SELECT LAST(field) AS [expression]
FROM table
[WHERE ...]
[GROUP BY ...]
[ORDER BY ...]

The LAST function is used to return the value of the last record in the designated field
Therefore, this function returns a single value. Since the records are returned in an arbitrary
order, the last record will also be arbitrary. You can use the ORDER BY clause to order the
records.

The companion FIRST function returns the first record in the designated field.

This code finds the last birthdate in a table of MediCare patients that is ordered by the age
field.

SELECT LAST(birthdate) AS LastBirthDate


FROM MediCarePatients
ORDER BY age
OPERATION: LEFT JOIN
FROM table1 LEFT JOIN table2
ON table1.field1 compopr table2.field2

The LEFT JOIN and the similar RIGHT JOIN operations can be used in any FROM clause to
combine records from two tables. The LEFT JOIN operation is used to create a left outer join
and includes all of the records from the first (left) of the two tables, even if there are no
matching values for records in the second. The RIGHT JOIN operation is used to create a right
outer join and includes all of the records from the second (right) of the two tables, even if there
are no matching values for records in the first.

Although a LEFT JOIN or RIGHT JOIN operation can be nested inside an INNER JOIN, the
converse is not true. An INNER JOIN operation cannot be nested inside a LEFT JOIN or
RIGHT JOIN.

Using the tables 'Employee' and 'Project', the LEFT JOIN operation would return the names of
all employees whether or not they were currently engaged in any project, but with project
names where applicable:

SELECT Employee.username, Project.ProjectName


FROM Employee LEFT JOIN Project
ON Employee.EmployeeID = Project.EmployeeID;

Using the same tables, the RIGHT JOIN operation would return the names of all projects,
whether or not any of the employees were currently working on them, but with employee
names where applicable:

SELECT Employee.username, Project.ProjectName


FROM Employee RIGHT JOIN Project
ON Employee.EmployeeID = Project.EmployeeID;

The above two examples are in contrast to the INNER JOIN example which only returns those
records in which the data in the joined fields is the same. i.e. only records for employees
currently engaged in projects.

Microsoft warns, "If you try to join fields containing Memo or OLE Object data, an error will
occur."
OPERATION: LIKE
SELECT list
FROM table
WHERE expression [NOT] LIKE 'string'

The LIKE operator allows you to compare values in a field to a string (or pattern) and see if
there is a match. In the first example, a list is created of authors who have written a 'Cook
Book'.

SELECT AuthorName FROM BookList


WHERE BookType LIKE 'Cook Book'

By using NOT, you can select everything that does not match a specific string. Adding NOT to
the previous example will create a list of all authors in BookList who have not written a 'Cook
Book'.

SELECT AuthorName FROM BookList


WHERE BookType NOT LIKE 'Cook Book'

The LIKE operator can use what are called "wild card characters" to create search pattern
strings. Here are five wild card characters:

Wild Card Description

* Any string composed of zero or more characters

? Any single character

# Any single digit

[] Any single character matching the specified set or range

[!] Any single character not matching the specified set or range

The use of wild card characters, in the form of a regular expression, can be a very complex
subject. Fortunately, there are several simple ways to use wild cards that are very useful for
pattern matching. By placing a * before and after the string 'Cook Book' (i.e., '*Cook Book*' )
you can search for a book title that contains the string 'Cook Book'. The * will accept zero or
more characters in the book title before or after the phrase 'Cook Book'.

SELECT AuthorLastName FROM BookList


WHERE BookTitle LIKE '*Cook Book*'

Wild card characters can be combined together to create search patterns. In the next example,
the expression '[PT]*' searches for two patterns. It will look for all strings that start with a P and
have zero or more additional characters after the P. And it will also look for all strings that start
with a T and have zero or more additional characters after the T. So, Thompson would be
selected, but not Cussler.

SELECT AuthorLastName FROM BookList


WHERE AuthorLastName LIKE '[PT]*'
In the previous example, by adding a dash (-) between the P and the T, the search pattern will
look for all authors whose last name starts with P, Q, R, S, and T.

SELECT AuthorLastName FROM BookList


WHERE AuthorLastName LIKE '[P-T]*'

Here are a few simple examples of possible search patterns for numbers:

'[4-8]' Search for digits 4, 5, 6, 7, and 8

'[!4-8]' Search for digits 0, 1, 2, 3, and 9

'Chapter #' Search for digits 0-9 after the word Chapter
FUNCTION: MAX
SELECT MAX(field) AS [expression]
FROM table
[WHERE ...]
[GROUPBY ...]
[HAVING ...]

The MAX function is one of the aggregate functions that are used to calculate statistical
information for a specified numeric field in a query. The other aggregate functions are: AVG,
COUNT, MIN, STDEV, STDEVP, SUM, VAR, VARP. Note that all of these functions return a
single value.

The MAX function simply finds the highest, or maximum, value in a field.

This code finds the longest hospital stay by MediCare patients over the age of 65 and stores
that information in MaxStay.

SELECT MAX(DaysInHospital) AS [MaxStay]


FROM MediCarePatients
WHERE age > 65
FUNCTION: MIN
SELECT MIN(field) AS [expression]
FROM table
[WHERE ...]
[GROUPBY ...]
[HAVING ...]

The MIN function is one of the aggregate functions that are used to calculate statistical
information for a specified numeric field in a query. The other aggregate functions are: AVG,
COUNT, MAX, STDEV, STDEVP, SUM, VAR, VARP. Note that all of these functions return a
single value.

The MIN function simply finds the lowest, or minimum, value in a field.

This code finds the shortest hospital stay by a MediCare patient over the age of 65 and stores
that information in MinStay.

SELECT MIN(DaysInHospital) AS [MinStay]


FROM MediCarePatients
WHERE age > 65
CLAUSE: ORDER BY
SELECT fieldlist FROM table WHERE selectcriteria
[ORDER BY field1 [ASC | DESC ][, field2 [ASC | DESC ]][, ...]]]

The ORDER BY clause can be used to dictate the order of the records returned (i.e., how they
are sorted). The following example returns records listed primarily in order of tune type (jigs
then reels), and then for each type the relevant names are also listed in alphabetical order:

SELECT TuneType AS Type, Name FROM Tunes WHERE TuneType = 'jig' OR TuneType =
'reel'
ORDER BY TuneType, Name;

You can specify descending order (the default is ascending order) by adding the reserved word
DESC after the field name. The next example returns a list of all items in ascending
alphabetical order along with their prices in descending numerical order:

SELECT Item, Unitprice AS Price


FROM Products
ORDER BY Item, UnitPrice DESC;
DECLARATION: PARAMETERS
PARAMETERS name datatype [, name datatype [, ...]]

The PARAMETERS declaration creates parameters for a parameter query that you use
regularly. When you run the query interactively, you will be presented with a dialog box in
which you must enter the value(s) of the parameters. Each parameter consists of a name,
which will appear in the dialog box if the query is run interactively, and a valid data type. If the
name includes spaces or punctuation it must be enclosed in square brackets. For example, if
you regularly ran a query to return a list of products that you wanted to promote as bargains,
but wanted the freedom to alter the 'definition' of a bargain, you could use the following query
which allows you to specify the value of a Bargain at run time.

PARAMETERS Bargain Currency;


SELECT Item, unitPrice AS Price FROM Products
WHERE UnitPrice < Bargain;

Note that the PARAMETERS declaration must appear first. You can include more than one
parameter, but they must be seperated by commas (,). And finally, the PARAMETERS
declaration must end with a semi-colon.

The following example returns a list of tune names in response to criteria concerning the tune
type and musician imposed by the user:

PARAMETERS [Select a musician] Text, [Select a tune type] Text;


SELECT Name FROM Tunes
WHERE Type = [Select a tune type] AND Musician = [Select a musician];
OPERATION: RIGHT JOIN
FROM table1 RIGHT JOIN table2
ON table1.field1 compopr table2.field2

The RIGHT JOIN and the similar LEFT JOIN operations can be used in any FROM clause to
combine records from two tables. The LEFT JOIN operation is used to create a left outer join
and includes all of the records from the first (left) of the two tables, even if there are no
matching values for records in the second. The RIGHT JOIN operation is used to create a right
outer join and includes all of the records from the second (right) of the two tables, even if there
are no matching values for records in the first.

Although a LEFT JOIN or RIGHT JOIN operation can be nested inside an INNER JOIN, the
converse is not true. An INNER JOIN operation cannot be nested inside a LEFT JOIN or
RIGHT JOIN.

Using the tables 'Employee' and 'Project', the LEFT JOIN operation would return the names of
all employees whether or not they were currently engaged in any project, but with project
names where applicable:

SELECT Employee.username, Project.ProjectName


FROM Employee LEFT JOIN Project
ON Employee.EmployeeID = Project.EmployeeID;

Using the same tables, the RIGHT JOIN operation would return the names of all projects,
whether or not any of the employees were currently working on them, but with employee
names where applicable:

SELECT Employee.username, Project.ProjectName


FROM Employee RIGHT JOIN Project
ON Employee.EmployeeID = Project.EmployeeID;

The above two examples are in contrast to the INNER JOIN example which only returns those
records in which the data in the joined fields is the same. i.e. only records for employees
currently engaged in projects.

Microsoft warns, "If you try to join fields containing Memo or OLE Object data, an error will
occur."
STATEMENT: SELECT
SELECT [predicate] { * | table.* |
[table.]field1 [AS alias1] [, table.]field2 [AS alias2] [, ...] ] }
FROM tableexpression [, ...] [IN externaldatabase]
[WHERE... ] [NOT] [IN] (value1,[value2,[...] ] )
[GROUP BY... ]
[HAVING... ]
[ORDER BY... ]
[WITH OWNERACCESS OPTION]
[subqueryclause [subqueryclause [...] ] ]

The SELECT statement returns information from a database as a set of records without
altering the database. It searches the database, extracts the chosen columns and selects
those records that meet the criteria, sorting and grouping the results into a specified order.

A SELECT statement can be nested inside of another SELECT statement which is nested
inside of another SELECT and so on. When a SELECT is nested it is refered to as a subquery
clause.

At its simplest, you can use an asterisk ( * ) to select all of the fields in a table (in this case the
table 'Musicians' ):

SELECT * FROM Musicians;

Or you can be more selective and choose just one or a few of the fields in a table, and they will
be returned in the order listed:

SELECT MusicianName, Instrument FROM Musicians;

You can also have a query display a field under a different heading than the one used in the
table by establishing an "alias" with the reserved word AS:

SELECT MusicianName AS Musician, Instrument


FROM Musicians;

...and you can even have a query combine two or more fields from a table into one field in the
returned list under a new heading using the ampersand character:

SELECT Name, City & ", " & Country AS Location


FROM Customers;

WHERE

You can use the WHERE clause to further focus your selection by specifying certain criteria to
be met by the values. The following example returns the names of all musicians who play the
flute:

SELECT MusicianName AS Musician FROM Musicians


WHERE Instrument = 'flute';

...and this example returns the names of all jigs in a 'Tunes' table:
SELECT TuneName AS Name, Source1 AS Recording FROM Tunes
WHERE TuneType = 'jig';

You can combine more than one criterion in a WHERE clause using any of the logical
operators. Here the query returns a list of all items which are blue and cost less than $100:

SELECT Item, UnitPrice AS Price FROM Products


WHERE Color = 'blue' AND UnitPrice < 100;

The optional, reserved word IN can be used either as a clause or as an operator.

If you want to get fields from a database other than the one you are currently working in, you
use the IN as a clause:

SELECT Name, Address


FROM PianoTuners IN USAPiano.mdb
WHERE state='TN';

If the database is a non-Microsoft Jet database, you must append a semicolon ( ; ) to the
database file name and enclose it within a pair of single ( ' ) or double quotes ( " ).

SELECT Name, Address


FROM PianoTuners IN "InstrumentTuners.xls;"
WHERE state='TN';

You can also specify a path and designate the type of file. Note the position of the ( ; ):

SELECT Name, Address


FROM PianoTuners IN "C:\Music\InstrumentTuners.xls" "Excel 5.0;"
WHERE state='TN';

When used as an operator, IN can determine if the values of a specified expression matches
any values in a specified list. This example determines if any piano tuners live in 'Knoxville',
'Nashville', or 'Memphis'. A pair of single quotes must enclose each value and commas must
separate each value:

SELECT * FROM TennPianoTuners


WHERE City IN ( 'Knoxville', 'Nashville', 'Memphis' );

You can also add a NOT. This causes the query to select all values other than those listed:

SELECT * FROM TennPianoTuners


WHERE City NOT IN ( 'Knoxville', 'Nashville', 'Memphis' );

The SELECT statement can optionally be followed by one of these four predicates: ALL,
DISTINCT, DISTINCTROW, TOP. These limit the number of records returned.

The ALL predicate is the default, but it is rarely used. Note that the following two code
examples yield the exact same results:

SELECT *
FROM RockAndRoll
WHERE Artist = 'Elvis';

SELECT ALL *
FROM RockAndRoll
WHERE Artist = 'Elvis';

The DISTINCT predicate is used to omit duplicate values just in a field. Consider a table of
names, where you have the last name, "Jones", repeated numerous times. This code returns
only one "Jones":

SELECT DISTINCT LastName


FROM SongWriters;

The DISTINCTROW predicate is used to omit duplicate values in an entire record of fields.
This can be very useful when you use a INNER JOIN to join two tables together and you do
not want any duplication. This code create a table that does not repeat any of the last names:

SELECT DISTINCTROW LastName


FROM SongWriters INNER JOIN Performers
ORDER BY LastName;

The TOP predicate returns the specified number of records from the top of the specified table.
The following example returns the first 3 records:

SELECT TOP 3 MusicianName AS Musician, Instrument


FROM Musicians;

You can also carry out calculations on fields containing numeric values using the aggregate
functions:

AVG - average
COUNT - count how many items
MAX - maximum value
MIN - minimum value
STDEV - sample standard deviation
STDEVP - standard deviation
SUM - add the values
VAR - sample variance
VARP - variance

This next example uses the COUNT function to count the number of items that have an entry in
the SalePrice field (i.e. they are on sale) and returns that number under the heading
'ReducedCount':

SELECT COUNT(SalePrice) AS ReducedCount


FROM Products;

...and this next one returns current prices along with what the prices would be after a 10%
increase:

SELECT Item, UnitPrice AS CurrentPrice, UnitPrice * 1.1 AS IncreasedPrice


FROM Products;

...and this one lists all items that are reduced along with the price and the amount of the
reduction:

SELECT Item, SalePrice AS Price, UnitPrice - SalePrice AS Reduction


FROM Products
WHERE SalePrice <> Null;

Of course, you may want to select fields from more than one table, and you can do that as well.
In this case it is best to precede a field name with the name of the table from which it comes,
followed by the dot operator ( . ). You must do this for fields of the same name, but from
different tables that are used in the SELECT statement. The following example uses two
tables, Task and Assignment, and returns the names of all Tasks belonging to Assignments
that are incomplete:

SELECT Task.Name, Task.TaskID


FROM Task INNER JOIN Assignment
ON Task.TaskID = Assignment.TaskID
WHERE Assignment.CompletionDate Is Null;

As an alternative to using the explicit INNER JOIN syntax, columns from multiple tables can be
combined in a single query by specifying the appropriate table list, and applying the filter
condition in the WHERE clause. This is illustrated in the following query, which returns the
same recordset as the previous example:

SELECT Task.Name, Task.TaskID


FROM Task, Assignment
WHERE Task.TaskID = Assignment.TaskID
AND Assignment.CompletionDate Is Null;

GROUP BY

The optional GROUP BY clause groups into a single record all records that have identical
values in a particular field or combination of fields. The following example returns a list of the
different products in the Product field of Suppliers.

SELECT Product FROM Suppliers GROUP BY Product;

HAVING

The HAVING clause is optional and qualifies a GROUP BY clause. It is similar to the WHERE
clause but determines which records are displayed after they have been grouped. The
following example displays a list of different items, along with their count, but only where there
are more than one.

SELECT Item, Count(Item) AS Tally FROM Products


GROUP BY Item HAVING Count(Item) > 1;

ORDER BY

The ORDER BY clause can be used to dictate the order of the records returned. The following
example returns records listed primarily in order of tune type (jigs then reels), and then for each
type the relevant names are also listed in alphabetical order.

SELECT TuneType AS Type, Name FROM Tunes WHERE TuneType = 'jig' OR TuneType =
'reel'
ORDER BY TuneType, Name;

WITH OWNERACCESS OPTION


In a multi-user environment utilizing secure workgroups, the WITH OWNERACCESS OPTION
declaration allows the query to be executed with the same permissions as the owner of the
query.
STATEMENT: SELECT SUBQUERY
SELECT selectstatement
(SELECT selectstatement
(SELECT selectstatement
( ... ) ) ) )

When a SELECT statement is nested inside of a DELETE, INSERT ... INTO, SELECT,
SELECT ... INTO, or a UPDATE statement, it is refered to as a subquery clause.

In this example we create a table of Medicare patients who also have dental insurance. The
social security number, ssn, is used as a key to compare the two tables, MediCarePatients and
DentalIns.

SELECT * FROM MediCarePatients


WHERE ssn IN
(SELECT ssn FROM DentalIns);

If we use a NOT, we create a table of Medicare patients who do not have dental insurance:

SELECT * FROM MediCarePatients


WHERE ssn NOT IN
(SELECT ssn FROM DentalIns);

There are three reserved words, ALL, ANY, and SOME, that can be used in subqueries to
make comparisons. However, Microsoft states that ALL and SOME are synonymous.

Consider the two following examples. The "< ALL" comparison will create a list of AvgEggSize
from BillsBirdNestList that contains only those entries that are smaller than the smallest
AvgEggSize value in LindasBirdNestList.

In contrast, the "< ANY" comparison will create a list of AvgEggSize from BillsBirdNestList that
contains only those entries that are smaller that the largest AvgEggSize value in
LindasBirdNestList.

SELECT AvgEggSize FROM BillsBirdNestList WHERE AvgEggSize < ALL (SELECT


AvgEggSize FROM LindasBirdNestList);

SELECT AvgEggSize FROM BillsBirdNestList WHERE AvgEggSize < ANY (SELECT


AvgEggSize FROM LindasBirdNestList);
CLAUSE: WHERE
DELETE [table | *] FROM table WHERE selectcriteria

SELECT table | * FROM table WHERE selectcriteria

UPDATE table SET newvalue WHERE selectcriteria

The WHERE clause is used with the DELETE, SELECT, and UPDATE statements to specify a
selection criteria.

However, the WHERE clause is optional. Consider the following SELECT example which does
not use a WHERE. This simple query will return all rows from the table SongWriters:

SELECT * FROM SongWriters;

The addition of a WHERE to the previous example allows you to efficiently narrow the values
that will be selected. In this example, we narrow the criteria to only 'Jazz':

SELECT * FROM SongWriters WHERE MusicType='Jazz';

By using the AND logical operator we can further narrow the criteria:

SELECT * FROM SongWriters WHERE MusicType='Jazz' AND YearWritten=1940;

You can also use the OR logical operator:

SELECT * FROM SongWriters WHERE MusicType='Jazz' OR MusicType='Blues';

Within a WHERE clause, you can link up to a total of forty (40) expressions using logicical
operators:

SELECT * FROM SongWriters WHERE MusicType='Jazz' OR MusicType='Blues' OR


MusicType='Gospel' AND YearWritten>1939 AND YearWritten<1946;
FUNCTION: STDEV
SELECT STD(field) AS [expression]
FROM table
[WHERE ...]
[GROUPBY ...]
[HAVING ...]

The STDEV function is one of the aggregate functions that are used to calculate statistical
information for a specified numeric field in a query. The other aggregate functions are: AVG,
COUNT, MAX, MIN, STDEVP, SUM, VAR, VARP. Note that all of these functions return a
single value.

The STDEV function finds the standard deviation by using a portion, called a sample, of the
total number of values in a field. This is a time saver when dealing with extremely large tables
and can be shown to be statistically valid. In comparison, the STDEVP function uses all of the
values to calculate the standard deviation. There must be at least two values in the field or the
standard deviation will not be calculated and a NULL is returned.

This code finds the standard deviation of the age of the MediCare patients in a hospital (by
using a sample) and stores that information in SDAge.

SELECT Var(Age) AS [SDAge]


FROM MediCarePatients
FUNCTION: STDEVP
SELECT STDEVP(field) AS [expression]
FROM table
[WHERE ...]
[GROUPBY ...]
[HAVING ...]

The STDEVP function is one of the aggregate functions that are used to calculate statistical
information for a specified numeric field in a query. The other aggregate functions are: AVG,
COUNT, MAX, MIN, STDEV, SUM, VAR, VARP. Note that all of these functions return a single
value.

The STDEVP function finds the standard deviation by using all of values in a field. In
comaparison, the STDEV function only uses a protion, called a sample, of the values to
calculate the standard deviation. There must be at least two values in the field or the standard
deviation will not be calculated and a NULL value is returned.

This code finds the standard deviation of the age for all MediCare patients in a hospital and
stores that information in DevAge.

SELECT STDEVP(Age) AS [DevAge]


FROM MediCarePatients
FUNCTION: SUM
SELECT SUM(field) AS [expression]
FROM table
[WHERE ...]
[GROUPBY ...]
[HAVING ...]

The SUM function is one of the aggregate functions that are used to calculate statistical
information for a specified numeric field in a query. The other aggregate functions are: AVG,
COUNT, MAX, MIN, STDEV, STDEVP, VAR, VARP. Note that all of these functions return a
single value.

The SUM function simply adds all of the values in a field and return the total sum.

This code finds the total number of days that MediCare patients stayed in the hospital and
stores that information in MCTotalDays.

SELECT SUM(DaysInHospital) AS [MCTotalDays]


FROM MediCarePatients
WHERE age > 65
FUNCTION: VAR
SELECT VAR(field) AS [expression]
FROM table
[WHERE ...]
[GROUPBY ...]
[HAVING ...]

The VAR function is one of the aggregate functions that are used to calculate statistical
information for a specified numeric field in a query. The other aggregate functions are: AVG,
COUNT, MAX, MIN, STDEV, STDEVP, SUM, VARP. Note that all of these functions return a
single value.

The VAR function finds the variance by using a portion, called a sample, of the total number of
values in a field. This is a time saver when dealing with extremely large tables and can be
shown to be statistically valid. In comparison, the VARP function uses all of the values to
calculate the variance. There must be at least two values in the field or the variance will not be
calculated and a NULL is returned.

This code finds the variance of the age of the MediCare patients in a hospital (by using a
sample) and stores that information in VarAge.

SELECT VAR(Age) AS [VarAge]


FROM MediCarePatients
FUNCTION: VARP
SELECT VARP(field) AS [expression]
FROM table
[WHERE ...]
[GROUPBY ...]
[HAVING ...]

The VARP function is one of the aggregate functions that are used to calculate statistical
information for a specified numeric field in a query. The other aggregate functions are: AVG,
COUNT, MAX, MIN, STDEV, STDEVP, SUM, VAR, . Note that all of these functions return a
single value.

The VARP function finds the variance by using all of values in a field. In comaparison, the VAR
function only uses a portion, called a sample, of the values to calculate the variance. There
must be at least two values in the field or the standard deviation will not be calculated and a
NULL value is returned.

This code finds the variance of the age for all MediCare patients in a hospital and stores that
information in VarAge.

SELECT VARP(Age) AS [VarAge]


FROM MediCarePatients
DECLARATION: WITH OWNERACCESS OPTION
sqlstatement
WITH OWNERACCESS OPTION

The WITH OWNERACCESS OPTION is a very specialized declaration which is designed to be


used in a secure multiuser environment. Normally, in such an environment, only members of
the designated working group, who log on with user names and passwords, have access to the
database. However, the optional WITH OWNERACCESS OPTION declaration allows non-
members to have permission to access the secure database (i.e., the user who submits the
query has the same permissions as the query's owner) This declaration requires access to the
database System.mdw file.

Note that this declaration is placed at the end of the SQL query:

SELECT * FROM AtomicBombPlans


WITH OWNERACCESS OPTION
STATEMENT: SELECT INTO
SELECT field1[, field2[, ...]] INTO newtable [IN externaldatabase]
FROM source

The SELECT INTO statement is used to create a make-table query. It is especially useful for
making backup copies of tables and reports, or for archiving records. The following example
makes a backup copy of the Customers table:

SELECT * INTO [Customers Backup]


FROM Customers;

You can also copy tables into another database by using the IN clause:

SELECT Suppliers.* INTO Suppliers IN 'Backup.mdb'


FROM Suppliers;

You don't need to copy the whole table. If you only want to copy a few fields, you can do so by
listing them after the SELECT statement. The following query creates a Fiddlers table by
extracting the names of fiddlers from a Musicians table:

SELECT Name INTO Fiddlers


FROM Musicians
WHERE Instrument = 'fiddle';

The fields which you copy into a new table need not come from just one table. You can copy
from multiple tables as demonstrated in the next example which selects fields from the two
tables Suppliers and Products to create a new table for Mexican Suppliers:

SELECT Suppliers.Name, Product, Products.UnitPrice


INTO [Mexican Suppliers]
FROM Suppliers INNER JOIN Products
ON Suppliers.ProductID = Products.ProductID
WHERE Suppliers.Country = 'Mexico';

The SELECT...INTO statement doesn't define a primary key for the new table, so you may
want to do that manually.
STATEMENT: TRANSFORM
PARAMETERS expression]
TRANSFORM aggregate function
SELECT anyselectstatement
PIVOT pivotfield [IN (value1 [, value2 [, ...] ] ) ]

The optional TRANSFORM statement applies an aggregate function to a SELECT statement


and creates a crosstab query to display the results.

There are eight aggregate functions: AVG, COUNT, MAX, MIN, STDEV, STDEVP, SUM, VAR,
VARP. They are used to calculate statistical information about a specific numeric field in a
query.

A crosstab query is table that has both a row header and a column header. The data generated
by using the aggregate function is listed in the table under a cross-reference between these
row and column header. This is a convenient way to display data in a compact, summarized
format.

The PIVOT portion of the statement is used to determine the column headers. You can use the
returned values from pivotfield as headers. The term "pivoting" signifies that a result table
generates headers based upon the selected values. For example, if you selected a specific
period of years over which to generate data, then your column headers would have a column
for each year. Or you can used the optional IN clause to create fixed headers by declaring
value1, value2, ...

The code example can be divided into four parts:

First, using an optional PARAMETERS declaration, the example displays a dialog box asking
the user to choose the year for which to return figures.

Next the TRANSFORM statement applies the SUM aggregate function. Note that the
TRANSFORM statement must always appear after any PARAMETER statement and before
the SELECT statement.

Third, comes the mandatory SELECT statement.

Finally, the query returns for the selected year a list of different instruments with sales figures
for each month (i.e., The PIVOT is pivoting over months, therefore each month, for which sales
occurred, has an individual column):

PARAMETERS [Year?] Long;


TRANSFORM Sum([Shipping].Quantity * [Shipping].UnitPrice) AS GrossIncome
SELECT PurchaseOrder.InstrumentName FROM PurchaseOrder
INNER JOIN (InstrumentCataloq INNER JOIN [Shipping]
ON InstrumentCatalog.CatNum = [Shipping].CatNum)
ON PurchaseOrder.OrderNum = [Shipping].OrderNum
WHERE DatePart("yyyy", PurchaseDate) = [Year?]
GROUP BY PurchaseOrder.InstrumentName
ORDER BY PurchaseOrder.InstrumentName
PIVOT DatePart("m",PurchaseDate);

A possible result table for the above example:


JAN MAR MAY JUN AUG SEP OCT NOV DEC
drum 87.50 0.00 0.00 175.00 0.00 350.00 350.00 175.00 350.00
cornet 114.00 228.00 114.00 0.00 114.00 0.00 228.00 556.00 228.00
flute 179.00 179.00 0.00 0.00 179.00 0.00 358.00 716.00 358.00
trumpet 326.00 0.00 326.00 326.00 0.00 0.00 652.00 652.00 978.00

Note: For information about using "wildcard" characters, such as ?, with SQL, please read the
Knowledge Base Article
A100219: SQL Wild Cards, ADO and Microsoft Access.
OPERATION: UNION
[TABLE] query1
UNION [ALL]
[TABLE] query2
[UNION [ALL]
[TABLE] queryn [ ... ]]
[GROUP BY grouplist, [...]]

You use the UNION operation to merge the results from any combination of two or more
queries, or SELECT statements, or tables, into a single table. The following example merges
two queries that selected jigs and reels respectively from a Tunes table, and tags the second
onto the end of the first, thus listing jigs and reels together:

TABLE Jigs UNION ALL TABLE Reels;

All queries in a UNION operation must request the same number of fields, though they don't
have to be of the same size or data type. By default, the UNION operation only returns unique
records, but by using the ALL predicate you ensure that all records are returned. This also
makes the query run faster.

The next example takes certain selected fields (as opposed to table, which takes all of them)
from the Customers table and joins them onto the end of the same number of selected fields
from the Suppliers table:

SELECT Name, City FROM Suppliers


WHERE Country = 'Mexico'
UNION SELECT Name, City FROM Customers
WHERE Country = 'Mexico';

You can use an ORDER BY clause at the end of the last query to specify the order of the
returned data:

SELECT Name, City, 'Supplier' AS Source


FROM Suppliers
WHERE Country = 'Canada'
UNION SELECT Name, City, 'Customer'
FROM Customers
WHERE Country = 'Canada'
ORDER BY City, Source;
STATEMENT: UPDATE
UPDATE table SET newvalue WHERE criteria

The UPDATE statement is used to change values in one, or more, or all of the records in a
table.

To updating one field:

UPDATE Project
SET ProjectName = 'Grindstone'
WHERE ProjectName = 'Hardwork';

To updating more than one field in a table:

UPDATE Products
SET ShippingWeight = '800lbs', ProductName = 'Grindstone MarkII', Price = '$348.71'
WHERE CatalogNumber = 'GS1097';

Note that UPDATE doesn't generate a result set.

If you want to know which records will be modified, first run a SELECT query that uses the
same criteria. If the results are satisfactory, then run the update query.

UPDATE Musicians
SET Instrument = 'violin'
WHERE Instrument = 'fiddle'
AND MusicType = 'classical';

The next example updates the TrainFares table to account for a 10% increase in the cost of a
single ticket on the Edinburgh line:

UPDATE TrainFares
SET Fare = Fare * 1.1
WHERE Line = 'Edinburgh'
AND Journey = 'single';

You can use a "cascade update" operation to update records from tables that are in a one-to-
many relationship with other tables. A cascade update causes the records in tables that are on
the many side of the relationship to be updated when the corresponding record in the one side
of the relationship is updated.

The Jet database engine will cascade update if the relationships between tables are configured
to enable this option. While Jet SQL gives us a mechanism to establish a relationship (using
the CONSTRAINT clause) it does not give us any method to configure relationships to enable
cascading operations. However, if a relationship has been configured to enable cascading
operations, for example by using Microsoft Access or DAO (Data Access Objects) , the Jet
SQL UPDATE and DELETE) statements will cascade.