You are on page 1of 9

507375355.

doc

1 Overview
This handout introduces INSERT, UPDATE and DELETE query types.
It also covers aggregate functions and GROUP BY, and operators (arithmetic, comparison,
logical) that can be used in queries.

2 Aggregate Functions and Group By

Aggregate functions perform a calculation on a set of values and return a single value. The
set of values is usually the values in a given column.
Useful aggregate functions include the following.

Function Description
AVG calculate the average value for a group e.g.
SELECT AVG(price) FROM titles
COUNT counts the number of items in a group; can use it in different ways –
count(*) counts all the rows in a table, including rows that contain NULL values
count(expression) counts the number of rows with non-NULL values in a specific
column, where expression is the name of the column
count(DISTINCT expression) counts the number of distinct non-NULL values in a
specific column, where expression is the name of the column.
Examples (in pubs database):
SELECT COUNT(*) FROM titles – returns a value of 18 because there are 18 rows in
titles table
SELECT COUNT(price) FROM titles – returns a value of 16 because 2 titles have a value
of NULL for the price
SELECT COUNT(DISTINCT price) FROM titles – returns a value of 11 because there
are 11 different prices in the table, excluding NULL values
(see further information about DISTINCT below)
MAX returns the max value in a group e.g.
SELECT MAX (price) FROM titles
MIN returns the min value in a group
SELECT MIN (price) FROM titles
SUM sums all the values in a group
SELECT SUM (price) FROM titles

Aggregate functions are usually used with the GROUP BY operator – this specifies groups
for which the aggregate summary value should be calculated.

The syntax of the SELECT statement with GROUP BY is as follows (remember that
elements in square brackets – [] – are optional):
SELECT select_list
FROM table_source
[ GROUP BY group_by_expression ]

A group_by_expression is a list of one or more column names, separated by commas.


Any column that is in the select_list but is not summarised with an aggregate function must
be included in the group_by_expression.

Some examples follow.


Get the average price of a title:
SELECT AVG (price)
FROM titles

Page 1 of 9
507375355.doc

Get the average price of a business title:


SELECT AVG (price)
FROM titles
WHERE type = 'business'

Get the minimum title price:


SELECT MIN (price)
FROM titles

Get the average price of a title in each type:


SELECT 'Average Price' = AVG(price), type
FROM titles
GROUP BY type

(Note: in this query, the " 'Average Price' = AVG (price)" is to name the average price
column in the result set as 'Average Price'. Without this, the column will appear in the result
set with no name.)

The DISTINCT keyword can be used to eliminate duplicate rows from the query results.
When DISTINCT is not specified, all rows are returned.
DISTINCT can also be used with the SUM, AVG and COUNT aggregate functions – when
used with these, it removes duplicate values from the summarised value.

For example:
SELECT DISTINCT price
FROM titles

SELECT AVG(DISTINCT price)


FROM titles
WHERE type = 'business'

The result for this query is: ________

Without DISTINCT, the AVG function finds the average price of all business titles (the
average calculation sums all the prices and divides by the count of all business titles):

SELECT AVG(price)
FROM titles
WHERE type = 'business'

The result for this query is: __________

(You can check these results by using COUNT and SUM aggregates on the titles table, and
dividing the SUM value by the COUNT value – as you would for an average calculation.
You can use standard mathematical operators in SQL queries - / for division, * for
multiplication, + and -.)

3 INSERT
An insert query adds (inserts) rows into a table.
The query must specify the table to insert into, a list of columns for which values are being
supplied and the values for those columns.

Page 2 of 9
507375355.doc

INSERT [ INTO]
    { table_name }

    {    [ ( column_list ) ]
        { VALUES
            ( { DEFAULT | NULL | expression } [ ,...n] )
        }
    }

Example (should be done in the pubs db – to add a record to the Titles table):
INSERT INTO titles
(title_id, title)
VALUES ('TOS01', 'My Book')

Things to note about the INSERT query:


 Title_id is the primary key, but not an identity column (an identity column is like an
autonumber column in Access) – so the value must be supplied and must be unique.
 If a column is an identity column, you do not normally supply the value.
 Both fields are character types, so the values must be in single quotes
 The order of the values matches the order of the names in the column_list
 The 'INTO' keyword is optional – the query is the same without it.
 The column_list is optional – if the number of values supplied matches the number of
fields in the table, then you do not need to supply the column list.
In that case, the order of the list of values will be assumed to match the order of the
columns in the table.
However, it is good practice to name the fields in any case – as this makes it clear
what values are going into what fields, especially to someone not familiar with the
database schema.
 DEFAULT means that the default value specified for the column will be inserted. If a
value is not supplied for a column, the default value will also be inserted.
 NULL means that a NULL value will be inserted for the column.

SQL will check that the values supplied are valid for the data-type and any other rules/checks
applied to each column.
For example, if you tried:
INSERT INTO titles
(title_id, title)
VALUES ('tos1', My Book)

- you should get an error because the title is not enclosed in single quotes, as is necessary for
a character string.

4 UPDATE
An UPDATE query updates values in a table.
The query must specify the table to update, the columns to update and the values to update
the columns to.
The basic syntax is:

UPDATE {table_name }
SET { column_name = { expression | DEFAULT | NULL } } [ ,...n ]
{ [ WHERE < search_condition > ] }

Page 3 of 9
507375355.doc

 It is very important to specify the search_condition – otherwise you could update


ALL the rows in the table – unintentionally!
Therefore, it is good practice to type in the WHERE clause before typing the SET
clause.
 DEFAULT means that the default value specified for the column will be used.
 NULL means that a NULL value will be set for the column.

Example (to update the record we have just added):


UPDATE titles
SET title = 'Introduction to SQL Server', pub_id = '0877'
WHERE title_id = 'tos1'

Things to note:
 One or more columns can appear in the SET clause – e.g. could just have
UPDATE titles
SET title = 'Introduction to SQL Server'
WHERE title_id = 'tos1'

5 DELETE
A DELETE query is used to delete one or more rows from a table.

The basic syntax for a DELETE query is:


DELETE
    [ FROM ]
        { table_name }

    [ WHERE
        { < search_condition > }
    ]

 Like the UPDATE query, it is important to specify the WHERE clause, otherwise you
could accidentally delete ALL the records in a table, unintentionally!

Example – to delete the record we have just inserted:

DELETE FROM titles


WHERE title_id = 'tos1'

Things to note:
 The 'FROM' keyword is optional – the query is the same without it.
 If the WHERE clause is omitted i.e. just DELETE FROM titles – then ALL the
records in titles would be deleted.
 If you attempt to delete a row that has dependent rows (where the row you are
deleting has a Primary Key column and there are rows containing the corresponding
Foreign Key in other tables) then the row cannot be deleted, if referential integrity has
been enforced (by imposing a Foreign Key constraint – we will look at these later in
the course).

Page 4 of 9
507375355.doc

6 Mathematical Operators
As well as aggregate functions, SQL has operators for mathematical functions.
The most commonly used of these are shown below.

1.1 Arithmetic
Arithmetic expressions are used to perform mathematical operations on numeric data types
(int, float etc). They are often used in the select_list to produce values based on columns in
tables.
The arithmetic operators are:
+ (addition)
- (subtraction)
* (multiplication)
/ (division)
% (modulo – returns the integer remainder of a division e.g. 11 % 3 = 2.)

For example, to calculate the value of each sales order, multiply the quantity of the order by
the price for the title:
SELECT ord_num, qty, price, qty * price FROM sales s, titles t
WHERE s.title_id = t.title_id

1.2 Assignment
The assignment operator is the = sign.
This is used to specify an alternative column name for an expression in a SELECT list e.g.
SELECT 'Price ($)' = price, title FROM titles

Note: in SQL Server's T-SQL, this can also be achieved using the syntax 'AS column_name'
e.g. SELECT price AS 'Price ($)' , title FROM titles

In both cases, the alternative column name does not have to be in quotes if there are no
spaces in it.

Also used when writing T-SQL to assign a value to a variable in a SQL script (we will cover
the use of variables later in the course).
1.3 Comparison
Comparison operators test whether or not two expressions are equal or unequal. These
operators can be used on all data types except text, ntext and image (these are advanced data
types which we will cover later in the course).
They are generally used to specify fields to JOIN on and in the WHERE clause as search
conditions.
The result of a comparison operator has a Boolean data type – this means it has one of the
three (boolean) values TRUE, FALSE or UNKNOWN (NULL).
When used in a WHERE clause as a search condition, those rows that return a value of TRUE
for the condition will be included in the result set. Rows that return FALSE or UNKNOWN
will not be included in the result set.

The operators are listed in the table below, along with some examples of each.

Operator Description Examples


= Equal to To find all titles that have a price of 19.99:
SELECT title, title_id, price, p.pub_id, pub_name FROM titles t INNER
JOIN publishers p ON t.pub_id = p.pub_id WHERE t.price = 19.99

Page 5 of 9
507375355.doc

To find all titles of type 'business':


SELECT title_id, title FROM titles WHERE type = 'business'
< Less than To find all titles that have a price less than 20:
SELECT title, title_id, price FROM titles WHERE price < 20
> Greater than To find all titles that have a price greater than 10:
SELECT title, title_id, price FROM titles WHERE price > 10
<= Less than or equal To find all titles that have a price less than or equal to 20:
to SELECT title, title_id, price FROM titles WHERE price <= 20
>= Greater than or To find all titles that have a price greater than 10:
equal SELECT title, title_id, price FROM titles WHERE price >= 10
<> Not equal to To find all titles that have a price that is not 10:
SELECT title, title_id, price FROM titles WHERE price <> 10
To find all titles that are not of type 'business':
SELECT title_id, title, type FROM titles WHERE type <> 'business'
!= Not equal to (not SELECT title, title_id, price FROM titles WHERE price != 10
ANSI standard, but
is supported by
SQL Server)
!< Not less than (not SELECT title, title_id, price FROM titles WHERE price !< 20
ANSI standard, but
is supported by
SQL Server)
!> Not greater than SELECT title, title_id, price FROM titles WHERE price !> 20
(not ANSI
standard, but is
supported by SQL
Server)

1.3.1 NULLs in Comparisons – IS NULL/IS NOT NULL

NULL values have special treatment in comparisons. The ANSI standard for a comparison
operation where one of the values is NULL is for the comparison to return a value of NULL
(UNKNOWN).
For example, with the ANSI standard, a comparison such as '15 > NULL' would return
NULL (UNKNOWN).
This means a query such as

SELECT * FROM titles WHERE price = NULL

Will return no rows – because when the price in each row is compared to NULL, the return
value is NULL, so no row is included in the result set.

The way around this is to use IS NULL to search for actual NULL values:

SELECT * FROM titles WHERE price IS NULL

This would return all rows where there is a NULL value in the price column.
IS NOT NULL can be used to search for non-NULL values:
SELECT * FROM titles WHERE price IS NOT NULL

Note: in SQL Server, there is a setting called ANSI_NULLS –if this setting is turned on, then
the behaviour of comparisons to NULLs follows the ANSI standard, as described above. If
this setting is turned off, then comparisons such as 'WHERE price = NULL' will return rows

Page 6 of 9
507375355.doc

where the price is NULL. The default is for this setting to be on, so the behaviour defaults to
the ANSI standard.

1.4 Logical Operators


Logical operators are used to test for the truth of some condition – they return a boolean
value of either TRUE or FALSE. They are often used in the WHERE clause of a query.
We have already been using some logical operators in the WHERE clause of our SELECT
queries – where there is more than one search condition, or a join and a search condition, we
have used the logical operator AND to join the two conditions.
A logical AND operation between two values evaluates to true if both are TRUE.

The AND and various other logical operators are described in the table below. Examples of
each are also given.

Logical Operator Description/Examples


AND Takes two conditions, both of which are boolean expressions; returns TRUE if both
are TRUE; returns FALSE if one or both are not TRUE.

To find all titles that are of type 'business' and have a price greater than or equal to
10:
SELECT * FROM titles WHERE type = 'business' AND price >= 10

To find all titles that have a price greater than 10 and less than 20 (i.e. in the range 10
to 20):
SELECT title, title_id, price FROM titles WHERE price >= 10 AND price <= 20
BETWEEN Takes an operand (a value) to check and returns TRUE if the operand is within a
specified range (the operand must be >= the first value and <= the second value)

To find all titles with a price between 10 and 20:


SELECT title, title_id, price FROM titles WHERE price BETWEEN 10 AND 20
(this should give the same results as the second example given for AND above)

NOT BETWEEN can be used to return TRUE if the operand is not within the
specified range e.g.
SELECT title, title_id, price FROM titles WHERE price NOT BETWEEN 10 AND
20

IN Returns TRUE if the operand is equal to one of a list of expressions. The expressions
must be of the same data type as the operand e.g. if the operand is a number, then the
listed expressions must be numbers; if the operand is a character string, then the listed
expressions must also be character strings.

To find titles that are one of the types 'mod_cook' and 'trad_cook':
SELECT title_id, title, type, price FROM titles WHERE type IN ('mod_cook',
'trad_cook')
(IN is useful if there are more than 2 or 3 values to check for – for just a few values,
the comparisons can easily be ANDed together)

The list of values can be replaced with a subquery. A subquery is a select query that
returns a single column and is nested inside a SELECT, INSERT, UPDATE or
DELETE query. For example, to use a subquery to get a list of author_ids for authors
who have a royalty per book of less than 50:
SELECT au_lname, au_fname FROM authors WHERE au_id IN
(SELECT au_id FROM titleauthor WHERE royaltyper < 50)

Many queries expressed in this way can also be expressed as a join – this example
could be written as:

Page 7 of 9
507375355.doc

SELECT DISTINCT au_lname, au_fname FROM authors a INNER JOIN titleauthor


ta ON a.au_id = ta.au_id WHERE royaltyper < 50

However, sometimes a subquery is the only way to form the query.

NOT IN can be used to return TRUE when the value is not in the supplied list.
LIKE Returns TRUE if the operand matches a pattern – the operand is a character string.
The pattern can include regular characters and wildcards. The pattern is enclosed in
quotes, like a character string.

Wildcards are:
% - any string of characters
_ - (underscore) – to match any single character
[ ] – to match any character in a specified set or range e.g. [abcd] to match a or b or c
or d, [a-f] to match any character from a to f.
[^] – like [ ] but matches characters not in the range following the ^ e.g. [^t] to match
any character that is not t; [^a-d] to match any character that is not a,b,c or d.

(Note the ANSI SQL-99 standard specifies that a pattern such as [A-Z^T] should
match any upper case letter that is not T – but this does not work in SQL Server )

Examples:
To find books that have the word 'computer' in the title:
SELECT * FROM titles WHERE title LIKE '%computer%'

To find authors whose first name begins with any letter but ends in 'heryl':
SELECT * FROM authors WHERE au_fname LIKE '_heryl'

To find authors whose last name begins with C or K and ends in 'en' or 'on' (i.e. to
look for authors with a last name of Carson, Carsen, Karson or Karsen):
SELECT * FROM authors WHERE au_lname LIKE '[CK]ars[eo]n'

To find authors that have a last name that ends in 'arson' or 'arsen' but does not begin
with C or an L.
SELECT * FROM authors WHERE au_lname LIKE '[^CL]ars[eo]n'

NOT LIKE can be used to return TRUE when the operand does not match the
supplied pattern.

NOT Reverses the value of any other boolean operator or the value of a boolean value.
If the operand or boolean operator evaluates to TRUE, placing NOT before it returns
the value FALSE.
If the operand or boolean operator evaluates to FALSE, placing NOT before it returns
the value TRUE.
If the operand or boolean operator evaluates to UNKNOWN (NULL), placing NOT
before it returns the value UKNOWN (NULL).

Examples:
SELECT * FROM titles WHERE NOT( type = 'business' AND price >= 10)
SELECT title, title_id, price FROM titles WHERE price NOT BETWEEN 10 AND
20
SELECT au_lname, au_fname FROM authors WHERE au_id NOT IN
(SELECT au_id FROM titleauthor WHERE royaltyper < 50)
SELECT * FROM titles WHERE title NOT LIKE '%computer%'

OR TRUE if either Boolean expression is TRUE


Takes two conditions, both of which are boolean expressions; returns TRUE if one or
both of the conditions are TRUE; returns FALSE if both are not TRUE.

Page 8 of 9
507375355.doc

To find titles that are either mod_cook or trad_cook type:


SELECT title_id, title, type, price FROM titles WHERE type = 'mod_cook' OR
'trad_cook'
(note – this query can also be formed using the IN operator)

1.5 Operator Precedence


When using more than one of the above operators, SQL has a defined order of precedence in
which to perform the operations.

Consider the following select statement:


SELECT 2 * 4 + 5

This could evaluate to 13 [(2 * 4) + 5] or to 18 [ (4+5) * 2 ].


However, the order of precedence used by SQL is to perform multiplication before addition –
so this would actually evaluate to 13.
The full order of precedence for the operators covered in this handout is as follows (the first
line are the highest precedence, the last line is the lowest):

*, /,%
+,-
=, >, <, >=, <=, <>, !=, !>, !<
NOT
AND
BETWEEN, IN, LIKE, OR

Operators appearing on the same line above are of equal precedence – these are evaluated
from left to right (depending on where they appear in the expression).

For example:
SELECT 2 * 4 + 5 – 3
evaluates to 10 (2*4 = 8, 8 + 5 = 13, 13-3 = 10).

However, if parentheses are used, the most deeply nested parentheses are evaluated first. For
example:
SELECT 2 * (4 + (5 – 3) )
evaluates to 12 – because the innermost set of parentheses is evaluated first – 5-3 = 2.
The next set is (4 + 2) = 6.
Then 2 * 6 = 12.

In general, it is best to make use of parentheses (brackets) to ensure the order of evaluation is
as you want it to be. This also makes the expression easier to read.

Page 9 of 9

You might also like