You are on page 1of 47

CHAPTER ONE

SQL: QUERIES, CONSTRAINTS, &


TRIGGERS

Structured Query Language (SQL) is the most widely used commercial


relational database language.
SQL is a comprehensive database language. It has several aspects:
The Data Manipulation Language (DML):
This subset of SQL allows users to pose queries and to insert, delete, and
modify rows. Queries are the main focus of this chapter.
The Data Definition Language (DDL): This subset of SQL supports the
creation, deletion, and modification of definitions for tables and views.
Integrity constraints can be defined on tables, either when the table is
created or later.
Triggers and Advanced Integrity Constraints:
Triggers are actions executed by the DBMS whenever changes to the
database meet conditions specified in the trigger. We cover triggers in this
chapter.
SQL allows the use of queries to specify complex integrity constraint
specifications.
Security: SQL provides mechanisms to control users' access to data objects
such as tables and views.
Transaction Management: Various commands allow a user to explicitly
control aspects of how a transaction is to be executed.
Transaction is a series of actions or database access operations which
include reads and writes of database objects

SQL Schema
A schema is an object that contains other objects.
The concept of an SQL schema was incorporated with SQL
in order to group together tables and other constructs that
belong to the same database application.
A schema is created via the CREATE SCHEMA statement,
which can include all the schema elements definitions.
Alternatively, the schema can be assigned a name and
authorization identifier, and the elements can be defined
later.
For example, the following statement creates a schema
called COMPANY, owned by the user with authorization
identifier Uname. Note that each statement in SQL ends
with a semicolon.
CREATE SCHEMA COMPANY AUTHORIZATION Uname;

Tables of a Database
To assist you with creating a table, you use a Data Definition Language
(DDL) command that is CREATE TABLE, followed by a name.
CREATE TABLE TableName . . .
After creating a table, it becomes part of its database and you can use
that table over and over again.
you can explicitly attach the schema name to the relation name,
separated by a period. For example, by writing
CREATE TABLE COMPANY.EMPLOYEE ...
If you don't specify a particular schema, the default dbo schema takes
ownership of the table.
In some cases, you may want to create a table to test something and
you would not need to use that table the next time you connect to the
server. Such a table is referred to as a temporary table.
To create a temporary table, start its name with #, followed by the
desired name.
Once the table has been created, it would be available as long as you
are using the same connection to the server.
If you close Microsoft SQL Server, the table would be automatically
deleted.

CREATE TABLE Employees ( ssn CHAR(11),


name CHAR(30) ,
lot INTEGER)
Specifying Attribute Constraints and Attribute Defaults
Because SQL allows NULLs as attribute values, a constraint NOT
NULL may be specified if NULL is not permitted for a particular
attribute.
We can also define a default value for an attribute by appending the
clause DEFAULT <value> to an attribute definition.
If no default clause is specified, the default default value is NULL for
attributes that do not have the NOT NULL constraint.
lot INT NOT NULL DEFAULT 1
Another type of constraint can restrict attribute or domain values
using the CHECK clause following an attribute or domain definition.
For example, suppose that lot numbers are restricted to integer
numbers between 1 and 20; then,
we can change the attribute declaration of lot in the Employees
table to the following:
lot INT NOT NULL CHECK (lot > 0 AND lot < 21)

Specifying Key and Referential Integrity Constraints


The PRIMARY KEY clause specifies one or more attributes that make up the primary key
of a relation.
If a primary key has a single attribute, the clause can follow the attribute directly. For
example, the primary key of Employees can be specified as follows:
ssn INT PRIMARY KEY;
Referential integrity is specified via the FOREIGN KEY clause
CREATE TABLE Enrolled ( sid CHAR(20) ,
cid CHAR(20),
grade CHAR(10),
PRIMARY KEY (sid, cid),
FOREIGN KEY (sid) REFERENCES Students)
When a column has been marked as unique, during data entry, the user must provide a
unique value for each new record created.
If an existing value is assigned to the column, this would produce an error.
Giving Names to Constraints
We can name a constraint by preceding it with CONSTRAINT constraint-name
For example, we can name the primary key constraint of the Enrolled table as follows:
CONSTRAINT EnrolledKey PRIMARY KEY (sid, cid)
The names of all constraints within a particular schema must be unique.
A constraint name is used to identify a particular constraint in case the constraint must
be dropped later and replaced with another constraint.
Giving names to constraints is optional.

Identity Columns
To solve the problem of uniquely identifying a record, you can
create a column whose main purpose is to distinguish one record
from another.
The SQL allows you to create a column whose data type is an
integer type but the user doesn't have to enter data for that
column.
A value would automatically be entered into the field when a new
record is created.
This type of column is called an identity column.
You cannot create an identity column on an existing table, only on a
new table.
to indicate that a column would be used as an identity column after
its name and data type, type identity followed by parentheses.
Between the parentheses, enter the seed value, followed by a
comma, followed by the increment value. Here is an example:
CREATE TABLE StoreItems( ItemID int IDENTITY(1, 1) NOT NULL,
Category nvarchar(50),
[Item Name] nvarchar(100) NOT NULL,
Size varchar(20),
[Unit Price] money);

Renaming a Table
sp_rename ExistingTableName, TableNewName;
The names of tables should be included in single-quotes. Here is an
example:
sp_rename 'StaffMembers', 'Employees';
Deleting a Table
DROP TABLE TableName;
Referring to a Table
There are three main ways you can do : To refer to, or to indicate, a
table:
You can simply type its name. An example would be
Students
You can type the schema name, followed by the period operator,
followed by the name of the table.
Registration.Students
You can type the name of the database to which the table belongs,
followed by the period operator, followed by the schema, followed
by the period operator, and followed by the name of the table.
test.Registration.Students

Adding a New Column to a Table


In SQL, the basic formula to add a new column to a table is:
ALTER TABLE TableName
ADD ColumnName Properties
Here is an example:
ALTER TABLE Enrolled
ADD grade char(10) NULL
Renaming a Column

sp_rename 'TableName.ColumnName', 'NewColumnName', N'COLUMN

Here is an example:
sp_rename Enrolled.grade', Grade', 'COLUMN'
Deleting a Column
ALTER TABLE TableName
DROP COLUMN ColumnName
Here is an example:
ALTER TABLE Enrolled
DROP COLUMN Grade;

Creating a Record
The DDL command to perform data entry is INSERT INTO combined
with VALUES.
The primary statement uses the following syntax:
INSERT INTO TableName VALUES(Column1, Column2, Column_n);

The VALUES keyword indicates that you are ready to list the values
of the columns.
The values of the columns must be included in parentheses.
If the column is a BIT data type, you must specify one of its values
a s 0 o r 1.
If the column is a numeric type, you should pay attention to the
number you type.
If the column was configured to receive an integer (int, bigint,
smallint), you should provide a valid natural number without the
decimal separator.
If the column is for a decimal number (float, real, decimal,
numeric), you can type the value with its character separator (the
period for US English).

Adjacent Data Entry


The most common technique of performing data entry requires that you
know the sequence of fields of the table in which you want to enter data.
With this subsequent list in mind, enter the value of each field in its
correct position.
During data entry on adjacent fields, if you don't have a value for a
numeric field, you should type 0 as its value.
For a string field whose data you don't have and cannot provide, type two
single-quotes '' to specify an empty field.
Example:
INSERT INTO Employees VALUES(1246700, 'Lealem', 20);
Random Data Entry
The adjacent data entry we have performed requires that you know the
position of each column.
To perform data entry in an order of your choice, you must provide your
list of the fields of the table.
You can either use all columns or provide a list of some columns but in
your own order.
In the same way, you don't have to provide data for all fields, just those
you want, in the order you want.
INSERT INTO Employees(ssn, name, lot) VALUES(1246700, 'Lealem', 20);

Creating Multiple Records


In previous sections, we added a single record to each use of the INSERT
formula.
You can add various records with one call to INSERT.
INSERT INTO Employees(ssn, name, lot)
VALUES(1246700, 'Lealem', 20),
(1167867,'Robel Marshall', 6),
(1354367, 'Dr. Yonas', 28);
Outputting the Insertion Result
The formula to use it is:
INSERT INTO TableName
OUTPUT INSERTED.Columns
VALUES(Value_1, Value_2, Value_X)
Here is an example:
INSERT INTO Employees(ssn, name, lot)
OUTPUT inserted.*
VALUES(1246700, 'Lealem', 20),
(1167867,'Robel Marshall', 6),
(1354367, 'Dr. Yonas', 28);

Data Entry With an Identity Column

After creating an identity column, when performing data


entry, don't specify a value for that column. Here is an
example:

CREATE TABLE StoreItems ( ItemID int identity(1, 1) NOT NULL,


Category nvarchar(50),
[Item Name] nvarchar(100) NOT NULL,
Size nvarchar(20),
[Unit Price] money );
GO
INSERT INTO StoreItems(Category, [Item Name], Size, [Unit Price])
VALUES(N'Men', N'Simplicity Leather Dress Oxfords', N'9', 65.85);
GO

If you provide a value for the identity column, you would receive an error

Data Entry and Functions

You can involve a function during data entry.


As an example, you can call a function that returns a value and assign that
value to a column.

INSERT INTO RepairOrders(CustomerName, CustomerPhone, RepairDate)


VALUES(N'Annette Berceau', N'301-988-4615', GETDATE());
the user will enter only the customer name and phone number.

Basic Retrieval Queries in SQL


We will present a number of sample queries using the following
table definitions:
Sailors( sid: integer, sname: string, rating: integer, age: real)
Boats( bid: integer, bname: string, color: string)
Reserves (sid: integer, bid: integer, day: date)
sid

sname

Rating

ag e

22

Desta

29

Birtukan

31

sid

bid

D ay

45.0

22

101

10/10/98

33.0

22

102

10/10/98

Lema

5 5 .5

22

103

10/8/98

32

And inet

25.5

22

104

58

Ruhama

10

3 5 .0

31

64

H one lign

35.0

71

Zelalem

10

74

H one lign

85
95

bid

bname

color

101

Inte rlake

blue

102

Inte rlake

red

10/7/98

103

Clipper

green

102

11/10/98

104

Marine

red

31

103

11/6/98

16 . 0

31

104

11/12/98

35.0

64

101

9/5/98

Alemu

25.5

64

102

9/8/98

Bob

63.5

74

103

9/8/98

Figure 3.1 An Instance of Sailors

Figure 3.3 An Instance of Boats

Figure 3.2 An Instance of Reserves

CREATE TABLE Sailors(sid int primary key,


sname varchar(30),
rating int, age real)
CREATE TABLE Boats(bid int primary key,
bname varchar(30),
color varchar(20))
CREATE TABLE Reserves(sid int,
bid int,
day date,
primary key(sid, bid, day),
foreign key(sid) References Sailors,
foreign key(bid) References Boats)

The basic form of an SQL query is as follows:


SELECT <attribute list>
FROM <table list>
WHERE <condition>;
<attribute list> is a list of attribute names whose values are to be retrieved by
the query.
<table list> is a list of the relation names required to process the query.
<condition> is a conditional (Boolean) expression that identifies the tuples to be
retrieved by the query.
Let us consider a simple example:
E.g. 1 Find the names and ages of all sailors
SELECT DISTINCT sname, age
FROM Sailors
The answer is a set of rows, each of which is a pair (sname, age).
If two or more sailors have the same name and age, the answer still contains
just one pair with that name and age.
The answer to this query with and without the keyword DISTINCT on the above
instances will be different.
The only difference is that the tuple for Honelign appears twice if DISTINCT is
omitted; this is because there are two sailors called Honelign and age 35.

Using an Alias Name for a Column and for a Relation


In your SELECT statement, after specifying the column(s), when you execute the
SQL statement, the name of each column appears as the column header.
If you want, you can display any string of your choice for the column header.
SELECT DISTINCT S.sname AS [Sailor Name], S.age AS Age
FROM Sailors S
A Combination or Expression of Columns
Using the SELECT keyword, we have learned to create a list of isolated columns.
These columns were produced separate of each other.
Instead of having separate columns, you can combine them to create a string or a
value that is in fact an expression.
For example, you can combine a first name and a last name to produce a full name
as an expression.
The most common operator used is the addition. It can be used to combine two or
more strings to get a new one. Here is an example:
SELECT FirstName + N' ' + LastName FROM Students;
Selecting the TOP Number of Records
to specify the maximum number of returned records, after the SELECT operator,
type TOP followed by an integral number.
SELECT TOP 5 * FROM Sailors;
Selecting the TOP Percent Records
SELECT TOP 25 PERCENT FirstName, LastName, HourlySalary
FROM Employees;

If a column has values that are difficult to identify, you can use a CASE conditional statement to customize the
result(s). Here is an example:
CREATE TABLE Persons(FirstName nvarchar(20),
LastName nvarchar(20),
GenderID int);

INSERT INTO Persons VALUES(N'Getu', N'Mola', 2), (N'Hora', N'Taye', 1),


(N'Markos', N'Kuma', 2), (N'Temam', N'Michael', 3), (N'Tomas', N'Yalew', 1), (N'Maru', N'Shaoul', 3),
(N'Netsanet', N'Muluken', 2);
SELECT FirstName, LastName, Gender =
CASE GenderID
WHEN 1 THEN N'Male'
WHEN 2 THEN N'Female'
ELSE N'Unknown'
END
FROM Persons
WHEN a Field's Value Meets a Criterion

Find all sailors with a rating above 7


SELECT S.sid, S.sname, S.rating, S.age
FROM Sailors AS S
WHERE S.rating > 7

When we want to retrieve all columns, SQL provides a convenient shorthand:

we can simply write SELECT *

Find the names of sailors Who have reserved boat number 103
SELECT S.sname
FROM Sailors S, Reserves R
WHERE S.sid = R.sid AND R.bid=103
This query contains join of two tables, followed by a selection by boat
number.
unless they are needed to resolve an ambiguity, the use of range variables
is optional
SELECT sname
FROM Sailors S, Reserves R
WHERE S.sid = R.sid AND bid=103
Only the occurrences of sid have to be qualified, since this column appears
in both the Sailors and Reserves tables.
An equivalent way to write this query is:
SELECT sname
FROM Sailors, Reserves
WHERE Sailors.sid = Reserves.sid AND bid=103
This query shows that table names can be used implicitly as row variables.

Find the sid of sailors who have reserved a red boat


SELECT R.sid
FROM Boats B, Reserves R
WHERE B.bid = R.bid AND B.color = 'red'
This query contains join of two tables, followed by a selection on
the color of boats.
If we want the names of sailors in the result, we must also consider
the Sailors relation, since Reserves does not contain this
information, as the next example illustrates.
Find the names of sailors who have reserved a red boat
SELECT S.sname
FROM Sailors S, Reserves R, Boats B
WHERE S.sid = R.sid AND R.bid = B.bid AND B.color = 'red'
This query contains a join of three tables followed by a selection on
the color of boats.
Find the colors of boats reserved by Lema
SELECT B.color
FROM Sailors S, Reserves R, Boats B
WHERE S.sid = R.sid AND R.bid = B.bid AND S.sname = 'Lema'

Find the names of sailors who have reserved at least one


boat
SELECT S.sname
FROM Sailors S, Reserves R
WHERE S.sid = R.sid
The joint of Sailors and Reserves ensures that for each
selected sname, the sailor has made some reservation.
Expressions and Strings in the SELECT Command
SQL supports a more general version of the select-list than
just a list of columns.
Each item in a select-list can be of the form
expression AS column_name
where expression is any arithmetic or string expression
over column names and constants, and
column_name is a new name for this column in the output
of the query.

Compute increments for the ratings of persons who have sailed two different
boats on the same day:
SELECT S.sname, S.rating+1 AS rating
FROM Sailors S, Reserves R1, Reserves R2
WHERE S.sid = R1.sid AND S.sid = R2.sid
AND R1.day = R2.day AND R1.bid <> R2.bid
SQL provides support for pattern matching through the LIKE operator, along with
the use of the wild-card symbols:
% (which stands for zero or more arbitrary characters) and
_ (which stands for exactly one, arbitrary, character).
Note that unlike the other comparison operators, blanks can be significant for the
LIKE operator. Thus, 'Jeff' = Jeff' is true while 'Jeff LIKE Jeff ' is false.
Find the ages of sailors whose name begins and ends with B and has at least three
characters.
SELECT S.age
FROM Sailors S
WHERE S.sname LIKE 'B%B'
The only such sailor is Bob, and his age is 63.5.
The following query results a list of Sailor whose sname begins with a, b, c, d, or e.

SELECT S.sname, S.age


FROM Sailors S
WHERE S.sname LIKE '[a-e]%
We may also use [a,b,c,d,e]

UNION, INTERSECT, AND EXCEPT


Find the names of the sailors who have reserved a red or a green boat:
SELECT S.sname
FROM Sailors S, Reserves R, Boats B
WHERE S.sid = R.sid AND R.bid = B.bid AND B.color = 'red'
UNION
SELECT S2.sname
FROM Sailors S2, Boats B2, Reserves R2
WHERE S2.sid = R2.sid AND R2.bid = B2.bid AND B2.color = 'green'
This query says that we want the union of the set of sailors who have
reserved red boats and the set of sailors who have reserved green boats.
Find the names of the sailors who have reserved both a red and a green
boat:
SELECT S.sname
FROM Sailors S, Reserves R, Boats B
WHERE S.sid = R.sid AND R.bid = B.bid AND B.color = 'red'
INTERSECT
SELECT S2.sname
FROM Sailors S2, Boats B2, Reserves R2
WHERE S2.sid = R2.sid AND R2.bid = B2.bid AND B2.color = 'green'

Our next query illustrates the set-difference


operation in SQL.
Find the sids of all sailor's who have reserved red
boats but not green boats.
SELECT S.sid
FROM Sailors S, Reserves R, Boats B
WHERE S.sid = R.sid AND R.bid = B.bid AND B.color = 'red'
EXCEPT
SELECT S2.sid
FROM Sailors S2, Reserves R2, Boats B2
WHERE S2.sid = R2.sid AND R2.bid = B2.bid AND B2.color = 'green'

Sailors 22, 64, and 31 have reserved red boats.


Sailors 22, 74, and 31 have reserved green boats.
Hence, the answer contains just the sid 64.

Find all sids of sailors who have a rating of 10 or reserved boat 104.
SELECT S.sid
FROM Sailors S
WHERE S.rating = 10
UNION
SELECT R.sid
FROM Reserves R
WHERE R.bid = 104
The first part of the union returns the sids 58 and 71.
The second part returns 22 and 31.
The answer is therefore, the set of sids 22, 31, 58, and 71.
In contrast to the default that duplicates are not eliminated unless
DISTINCT is specified in the basic query form,
the default for UNION queries is that duplicates are eliminated! To
retain duplicates, UNION ALL must be used.
Similarly, INTERSECT ALL retains duplicates, and EXCEPT ALL also
retains duplicates.

NESTED QUERIES
One of the most powerful features of SQL is nested queries.
A nested query is a query that has another query embedded within it;
the embedded query is called a subquery.
The embedded query can of course be a nested query itself; thus
queries that have very deeply nested structures are possible.
SELECT S.sname
FROM Sailors S
WHERE S.sid IN ( SELECT R.sid
FROM Reserves R
WHERE R.bid = 103 )
The nested subquery computes the set of sids for sailors who have
reserved boat 103(the set contains 22, 31, and 74), and
the top-level query retrieves the names of sailors whose sid is in this
set.
The IN operator allows us to test whether a value is in a given set of
elements
Note that it is very easy to modify this query to find all sailors who
have not reserved boat 103:
we can just replace IN by NOT IN!

Find the names of sailors who have reserved a


red boat:
SELECT S.sname
FROM Sailors S
WHERE S.sid IN ( SELECT R.sid
FROM Reserves R
WHERE R. bid IN (SELECT B. bid
FROM Boats B
WHERE B.color = 'red'))
To find the names of sailors who have not reserved a red boat, we replace
the outermost occurrence of IN by NOT IN.

Find the names of sailors who have reserved boat number 103:
SELECT S.sname
FROM Sailors S
WHERE EXISTS ( SELECT *
FROM Reserves R
WHERE R.bid = 103
AND R.sid = S.sid )
The EXISTS operator is another set comparison operator, such as IN.
It allows us to test whether a set is nonempty, an implicit
comparison with the empty set.
The occurrence of S in the subquery (in the form of the literal S.sid)
is called a correlation, and such queries are called correlated
queries.
We used a special symbol * because all we want to do is to check
that a qualifying row exists, and do not really want to retrieve any
columns from the row.
by using NOT EXISTS instead of EXISTS, we can compute the names
of sailors who have not reserved a boat number 103.

Set-Comparison Operators
We have already seen the set-comparison operators
EXISTS, and IN, along with their negated versions.
SQL also supports op ANY and op ALL,
where op is one of the arithmetic comparison
operators {<, <=, =, <>, >=, >}.
SOME is also available, but it is just a synonym for ANY.
Ex. Find sailors whose rating is better than some sailor
called Honelign.
SELECT S.sid
FROM Sailors S
WHERE S.rating > ANY ( SELECT S2.rating
FROM Sailors S2
WHERE S2.sname = 'Honelign' )
What if there were no sailor called Honelign?
In this case the comparison S.rating > ANY ... is defined to return false, and
the query returns an empty answer set.

Ex:- Find sailors whose rating is better than every sailor called
Honelign:
Just replace ANY with ALL in the WHERE clause of the outer
query.
SELECT S.sid
FROM Sailors S
WHERE S.rating > ALL ( SELECT S2.rating
FROM Sailors S2
WHERE S2.sname = 'Honelign' )

If there were no sailor called Honelign, the comparison


S.rating > ALL ... is defined to return true!
The query would then return the names of all sailors.
Ex:- Find the sailors with the highest rating:

SELECT S.sid
FROM Sailors S
WHERE S.rating >= ALL ( SELECT S2.rating
FROM Sailors S2 )
The subquery computes the set of all rating values in Sailors.
The outer WHERE condition is satisfied only when S.rating is greater than or equal
to each of these rating values, that is, when it is the largest rating value.
Note that IN and NOT IN are equivalent to = ANY and <> ALL, respectively.

AGGREGATE OPERATORS
SQL supports five aggregate operations, which can be applied on any
column, say A, of a relation:
1. COUNT ([DISTINCT] A): The number of (unique) values in the A column.
2. SUM ([DISTINCT] A): The sum of all (unique) values in the A column.
3. AVG ([DISTINCT] A): The average of all (unique) values in the A column.
4. MAX (A): The maximum value in the A column.
5. MIN (A): The minimum value in the A column.
Note that it does not make sense to specify DISTINCT in conjunction with
MIN or MAX (although SQL does not preclude this).
Ex:- Find the average age of all sailors:
SELECT AVG (S.age)
FROM Sailors S
Of course, the WHERE clause can be used to restrict the sailors considered
in computing the average age.
Ex:- Find the average age of sailors with a rating of 10:
SELECT AVG (S.age)
FROM Sailors S
WHERE S.rating = 10

Ex:- Find the name and age of the oldest sailor:


Consider the following attempt to answer this query:
SELECT S.sname, MAX(S.age)
FROM Sailors S
The intent is to return not only the maximum age but also the
name of the sailors having that age.
However, this query is illegal in SQL:
if the SELECT clause uses an aggregate operation, then it must use
only aggregate operations unless the query contains a GROUP BY
clause!
Therefore, we cannot use MAX (S.age) as well as S.sname in the
SELECT clause. We have to use a nested query to compute the
desired answer :
SELECT S.sname, S.age
FROM Sailors S
WHERE S.age = ( SELECT MAX (S2.age)
FROM Sailors S2 )

We can count the number of sailors using COUNT.


We use * as an argument to COUNT when we want to count all rows.
Ex:- Count the number of sailors:
SELECT COUNT (*)
FROM Sailors S
E.g. Count the number of different sailor names:
SELECT COUNT ( DISTINCT S.sname )
FROM Sailors S
If COUNT does not include DISTINCT, then COUNT (*) gives the same answer as
COUNT (x) ,where x is any set of attributes.
E.g. Find the names of sailors who are older than the oldest sailor with a rating of 10:
SELECT S.sname
FROM Sailors S
WHERE S.age > ( SELECT MAX ( S2.age )
FROM Sailors S2
WHERE S2.rating = 10 )
Using ALL, this query could alternatively be written as follows:
SELECT S.sname
FROM Sailors S
WHERE S.age > ALL ( SELECT S2.age
FROM Sailors S2
WHERE S2.rating = 10 )

The GROUP BY and HAVING Clauses


E.g. Find the age of the youngest sailor for each rating level.
If we know that ratings are integers in the range 1 to 10, we could
write 10 queries of the form:
SELECT MIN (S.age)
FROM Sailors S
WHERE S.rating = i
where i = 1,2, ... ,10.
Writing 10 such queries is tedious.
More important, we may not know what rating levels exist in
advance.
To write such queries, we need a major extension to the basic SQL
query form, namely, the GROUP BY clause.
In fact, the extension also includes an optional HAVING clause that
can be used to specify qualifications over groups.
for example, we may be interested only in rating levels > 6.

The general form of an SQL query with these extensions is:


SELECT [ DISTINCT] select-list
FROM from-list
WHERE 'qualification'
GROUP BY grouping-list
HAVING group-qualification

Using the GROUP BY clause, we can write the above


example as follows:
SELECT S.rating, MIN (S.age)
FROM Sailors S
GROUP BY S.rating

E.g. Find the age of the youngest sailor who is eligible to


vote( i.e. is at least 18 years old) for each rating level with
at least two such sailors:
SELECT S.rating, MIN (S.age) AS minimage
FROM Sailors S
WHERE S.age >= 18
GROUP BY S.rating
HAVING COUNT (*) > 1

E.g. For each red boat, find the number of reservations:


SELECT B.bid, COUNT (*) AS reservationcount
FROM Boats B, Reserves R
WHERE R.bid = B.bid AND B.color = 'red'
GROUP BY B.bid

Observe that this version of the preceding query is illegal (SQL disallows it):
SELECT B.bid, COUNT (*) AS reservationcount
FROM Boats B, Reserves R
WHERE R.bid = B.bid
GROUP BY B.bid
HAVING B.color = 'red'

Only the columns that appear in the GROUP BY clause can appear in the
HAVING clause, unless they appear as arguments to an aggregate operator in
the HAVING clause.
E.g Find the average age of sailors for each rating level that has at least two
sailors:
SELECT
S.rating, AVG (S.age) AS avgage
FROM
Sailors S
GROUP BY S.rating
HAVING
COUNT (*) > 1

After identifying groups based on rating, we retain only groups with at least
two sailors.

Data Joins

A data join is a technique of creating a list of records from more than one
table, using all columns from all tables involved, or selecting only the desired
columns from one or all of the tables involved.
In the SQL, the basic formula to create a join is:
SELECT WhatColumn(s)
FROM ChildTable
TypeOfJoin ParentTable
ON Condition

ChildTable specifies the table that holds the records that will be retrieved.
ParentTable specifies the table that holds the column with the primary key
that will control what records, related to the child table that will display.
Condition is a logical expression used to validate the records that will be
isolated. The condition can be created using the following formula:
Table1Column Operator Table2Column
To create the condition, you start with the ON keyword.
You can assign the primary key column of the parent table to the foreign key
column of the child table.
Because both columns likely have the same name, to distinguish them, their
names should be qualified.

Cross Joins
A cross join creates a list of all records from both tables
as follows:
1. the first record from the parent table is associated to
each record from the child table, then
2. the second record from the parent table is associated
to each record from the child table, and so on.
3. In this case, there is no need of a common column
between both tables. In other words, you will not use
the ON clause.
Ex.
SELECT S.sid, R.bid
FROM (Sailors S CROSS JOIN Reserves R)
Inner Joins
Imagine you have two tables that can be linked through
one's primary key and another's foreign key:

Genders

Persons

Notice that some records in the Persons table don't have an entry for the
GenderID column and were marked with NULL by the database engine.
When creating a query of records of the Persons table, if you want your list
to include only records that have an entry, you can create it as inner join.

SELECT Persons.PersonsID, Persons.FirstName, Persons.LastName,


Persons.GenderID, Genders.GenderID AS [Gender ID], Genders.Gender
From Persons INNER JOIN Genders ON Persons.GenderID = Genders.GenderID

An alternative to the INNER JOIN expression is to simply type


J O IN .
Outer Joins
Instead of showing only records that have entries in the child
table, you may want your query to include all records, including
those that are null.
To get this result, you would create an outer join. You have three
options:
Left Outer Joins
A left outer join produces all records of the child table.
The records of the child table that don't have an entry in the
foreign key column are marked as NULL.
SELECT s.sid, r.bid
FROM (Sailors s LEFT OUTER JOIN Reserves r on s.sid= r.sid)

Right Outer Joins


A right outer join considers all records from the parent
table and finds a matching record in the child table.
To do this, it starts with the first record of the parent table
and shows each record of the child table that has a
corresponding entry.
EX. SELECT s.sid, r.bid
FROM (Sailors s RIGHT OUTER JOIN Reserves r on s.sid= r.sid)

Notice that the query result starts with the first record of
the parent table, and
lists the records of the child table that have the entry
corresponding to that first record.
Then it moves to the next sid value of parent table.

Full Outer Joins


A full outer join produces all records from both the parent and the
child tables.
If a record from one table doesn't have a corresponding value in the
other table, the value of that record is marked as NULL.
SELECT s.sid, r.bid
FROM (Sailors s FULL OUTER JOIN Reserves r on s.sid= r.sid)

Views (Virtual Tables) in SQL


A view is a single table that is derived from other tables.
These other tables can be base tables or previously defined views.
A view does not necessarily exist in physical form; it is considered to
be a virtual table, in contrast to base tables, whose tuples are always
physically stored in the database.
A view is just a relation whose tuples/rows are not explicitly stored in
the database, but stores a definition.
Consider the Sailors and Reserves relations. Suppose that we are often
interested in finding the sailor ids, sailor names, boat ids, and day of
reservation of boats for sailors whose rating is greater than 5.
We can define a view for this purpose:

CREATE VIEW sailor_reserves(sailor_id,sailor_name,boat_id,day_of_reservation)


AS SELECT S.sid,S.sname,R.bid,R.day
FROM Sailors S, Reserves R
WHERE S.sid = R.sid AND S.rating > 5

If the optional arguments sailor_id,sailor_name,boat_id, and


day_of_reservation are omitted from the CREATE VIEW statement, the
column names sid, sname, bid, and day are inherited from the base
relations.
This view can be used just like a base table, or explicitly stored table, in
defining new queries or views.
Conceptually, whenever sailor_reserves is used in a query, the view
definition is first evaluated to obtain the corresponding instance of
sailor_reserves, and then the rest of the query is evaluated treating
sailor_reserves like any other relation referred to in the query.
Views are also valuable in the context of security and authorization
mechanism:
We can define views that give a group of users access to just the
information they are allowed to see.

For example, we can define a view that allows sailors to see other sailors
all information but not their age, and allow all sailors to access this view,
but not the underlying Sailors table.
CREATE VIEW sailor_info
AS SELECT sid,sname,rating
FROM Sailors
Renaming a View
sp_rename CurrentViewName, NewName;
E.g. sp_rename sailor_info, sailors_info;
Altering a View
After a view has been created, you may find out that it has an unnecessary
column, it needs a missing column, it includes unnecessary records, or
some records are missing.
Fortunately, you can change the structure or the code of a view.
For example, you can create a SELECT statement that includes a
modification of the existing code or a completely new statement.
ALTER VIEW sailors_info
AS SELECT sid,sname,rating,age
FROM Sailors
If we do not need a view any more, we can use the DROP VIEW command
to dispose of it.
For example,
DROP VIEW sailors_info;

The DELETE Command in SQL


The DELETE command removes tuples from a relation but not the relation itself.
It includes a WHERE clause, similar to that used in an SQL query, to select the
tuples to be deleted.
Tuples are explicitly deleted from only one table at a time.
However, the deletion may propagate to tuples in other relations if referential
triggered actions are specified in the referential integrity constraints of the DDL.
Depending on the number of tuples selected by the condition in the WHERE
clause, zero, one, or several tuples can be deleted by a single DELETE command.
A missing WHERE clause specifies that all tuples in the relation are to be
deleted; however, the table remains in the database as an empty table.
We must use the DROP TABLE command to remove the table definition.
DELETE FROM Sailors
WHERE sname = 'cherinet';
DELETE FROM Sailors
WHERE sid = 85;
DELETE FROM Sailors
WHERE rating >= '9';
DELETE FROM Sailors;

The UPDATE Command

The UPDATE command is used to modify attribute values of one or more selected
tuples.
a WHERE clause in the UPDATE command selects the tuples to be modified from a
single relation.
However, updating a primary key value may propagate to the foreign key values of
tuples in other relations if such a referential triggered action is specified in the
referential integrity constraints of the DDL.
The SET clause in the UPDATE command specifies the attributes to be modified and
their new values.
For example, to change the sid and sname of sailor with sid 22 in to 20 and 'Daniel',
respectively, we use:
UPDATE Sailors
SET
sid = 20,sname = 'Daniel'
WHERE
sid = 22;
UPDATE
Sailors
SET
rating = rating + 1
WHERE
age > 40;
It is also possible to specify NULL or DEFAULT as the new attribute value.
UPDATE Sailors
SET
rating = null
WHERE
age = 45;

You might also like