Você está na página 1de 9

Labsheet02 PostgreSQL7.

Use of SQL language in PostgreSQL (continued)


Most of the contents of this Labsheet is taken from the PostgreSQL 7.4.17 Documentation. It is
available at the following link: http://www.postgresql.org/docs/7.4/interactive/index.html

Aggregate Functions

Common aggregate functions are:


count
sum
avg (average)
max (maximum)
min (minimum)

Note: avg, min and max ignore tuples that have a null value for the specified attribute, but count
considers null values.

As an example, we can find the highest low-temperature reading anywhere with

Execute the following query using postgreSQL and see the results:

SELECT max(temp_lo) FROM weather;

Note: The aggregate max cannot be used in the WHERE clause


(This restriction exists because the WHERE clause determines the rows that will go into the
aggregation stage; so it has to be evaluated before aggregate functions are computed.)

Aggregates are also very useful in combination with GROUP BY clauses. For example, we can
get the maximum low temperature observed in each city with

Execute the following query using postgreSQL and see the results:

SELECT city, max(temp_lo)


FROM weather
GROUP BY city;

which gives us one output row per city. Each aggregate result is computed over the table rows
matching that city. We can filter these grouped rows using HAVING:

Execute the following query using postgreSQL and see the results:

SELECT city, max(temp_lo)


FROM weather
GROUP BY city
HAVING max(temp_lo) < 40;

which gives us the same results for only the cities that have all temp_lo values below 40. Finally,
if we only care about cities whose names begin with “S”, we might do
Execute the following query using postgreSQL and see the results:

SELECT city, max(temp_lo)


FROM weather
WHERE city LIKE ’S%’
GROUP BY city
Begum Durgahee 1
HAVING max(temp_lo) < 40;
Labsheet02 PostgreSQL7.4

The LIKE operator does pattern matching.

Constraints

The definition of a table may include the specification of integrity constraints.

To recap, the SQL command for creating an empty table has the following form:

create table <table> (


<column 1> <data type> [not null] [unique] [<column constraint>],
. . . . . . . . .
<column n> <data type> [not null] [unique] [<column constraint>],
[<table constraint(s)>]
);

Basically two types of constraints are provided: column constraints are associated with a single
column whereas table constraints are typically associated with more than one column.

For instance, to require positive product prices, you could use:

CREATE TABLE products (


product_no integer,
name text,
price numeric CHECK (price > 0)
);

You can also give the constraint a separate name. This clarifies error messages and allows you to
refer to the constraint when you need to change it. The syntax is:
CREATE TABLE products (
product_no integer,
name text,
price numeric CONSTRAINT positive_price CHECK (price > 0)
);

So, to specify a named constraint, use the key word CONSTRAINT followed by an identifier
followed by the constraint definition.

• NOT NULL Constraints

A not null constraint is directly specified after the data type of the column and the constraint
simply specifies that a column must not assume the null value.
For example:

CREATE TABLE products (


product_no integer NOT NULL,
name text NOT NULL,
price numeric
);

Begum Durgahee 2
Labsheet02 PostgreSQL7.4

The NOT NULL constraint has an inverse: the NULL constraint.

• UNIQUE Constraints

Unique constraints ensure that the data contained in a column or a group of columns is unique
with respect to all the rows in the table.

The keyword unique specifies that no two tuples can have the same attribute value for this
column. Unless the condition not null is also specified for this column, the attribute value null
is allowed and two tuples having the attribute value null for this column do not violate the
constraint.

For example:

CREATE TABLE products (


product_no integer UNIQUE,
name text,
price numeric
);

when written as a column constraint, and


CREATE TABLE products (
product_no integer,
name text,
price numeric,
UNIQUE (product_no)
);

when written as a table constraint.

If a unique constraint refers to a group of columns, the columns are listed separated by commas:
CREATE TABLE example (
a integer,
b integer,
c integer,
UNIQUE (a, c)
);

It is also possible to assign names to unique constraints:


CREATE TABLE products (
product_no integer CONSTRAINT must_be_different UNIQUE,
name text,
price numeric
);

• PRIMARY KEY

Technically, a primary key constraint is simply a combination of a unique constraint and a not-
null constraint.

So, the following two table definitions accept the same data:

CREATE TABLE products (


product_no integer UNIQUE NOT NULL,
name text,

Begum Durgahee 3
Labsheet02 PostgreSQL7.4

price numeric
);

CREATE TABLE products (


product_no integer PRIMARY KEY,
name text,
price numeric
);

Primary keys can also constrain more than one column; the syntax is similar to unique
constraints:
CREATE TABLE example (
a integer,
b integer,
c integer,
PRIMARY KEY (a, c)
);

A table can have at most one primary key (while it can have many unique and not-
null constraints).

• FOREIGN KEY

A foreign key constraint specifies that the values in a column (or a group of columns) must match
the values appearing in some row of another table. We say this maintains the referential integrity
between two related tables.

Say you have the product table that we have used several times already:
CREATE TABLE products (
product_no integer PRIMARY KEY,
name text,
price numeric
);

Let’s also assume you have a table storing orders of those products. We want to ensure that the
orders table only contains orders of products that actually exist. So we define a foreign key
constraint in the orders table that references the products table:

CREATE TABLE orders (


order_id integer PRIMARY KEY,
product_no integer REFERENCES products (product_no),
quantity integer
);

Now it is impossible to create orders with product_no entries that do not appear in the products
table.

We say that in this situation the orders table is the referencing table and the products table is the
referenced table. Similarly, there are referencing and referenced columns.

A foreign key can also constrain and reference a group of columns. As usual, it then needs to be
written in table constraint form. Here is a contrived syntax example:
CREATE TABLE t1 (
a integer PRIMARY KEY,
b integer,

Begum Durgahee 4
Labsheet02 PostgreSQL7.4

c integer,
FOREIGN KEY (b, c) REFERENCES other_table (c1, c2)
);

A table can contain more than one foreign key constraint. This is used to implement many-to-
many relationships between tables. Say you have tables about products and orders, but now you
want to allow one order to contain possibly many products (which the structure above did not
allow). You could use this table structure:
CREATE TABLE products (
product_no integer PRIMARY KEY,
name text,
price numeric
);

CREATE TABLE orders (


order_id integer PRIMARY KEY,
shipping_address text,
...
);

CREATE TABLE order_items (


product_no integer REFERENCES products,
order_id integer REFERENCES orders,
quantity integer,
PRIMARY KEY (product_no, order_id)
);

Note also that the primary key overlaps with the foreign keys in the last table.
We know that the foreign keys disallow creation of orders that do not relate to any products. But
what if a product is removed after an order is created that references it? SQL allows you to
specify that as well. Intuitively, we have a few options:
• Disallow deleting a referenced product
• Delete the orders as well
• Something else?

To illustrate this, let’s implement the following policy on the many-to-many relationship example
above: When someone wants to remove a product that is still referenced by an order (via
order_items), we disallow it. If someone removes an order, the order items are removed as
well.

CREATE TABLE products (


product_no integer PRIMARY KEY,
name text,
price numeric
);

CREATE TABLE orders (


order_id integer PRIMARY KEY,
shipping_address text,
...
);

CREATE TABLE order_items (


product_no integer REFERENCES products ON DELETE RESTRICT,
order_id integer REFERENCES orders ON DELETE CASCADE,
quantity integer,
PRIMARY KEY (product_no, order_id)
);

Modifying Tables

Begum Durgahee 5
Labsheet02 PostgreSQL7.4

PostgreSQL provides a family of commands to make modifications on existing tables.

You can
• Add columns,
• Remove columns,
• Add constraints,
• Remove constraints,
• Change default values,
• Rename columns,
• Rename tables.

All these actions are performed using the ALTER TABLE command

- Adding a Column

To add a column, use this command:


ALTER TABLE products ADD COLUMN description text;

The new column will initially be filled with null values in the existing rows of the table.

You can also define a constraint on the column at the same time, using the usual syntax:
ALTER TABLE products ADD COLUMN description text CHECK (description <> ”);

- Removing Column

To remove a column, use this command:


ALTER TABLE products DROP COLUMN description;

- Adding a Constraint

To add a constraint, the table constraint syntax is used. For example:


ALTER TABLE products ADD CHECK (name <> ”);
ALTER TABLE products ADD CONSTRAINT some_name UNIQUE (product_no);
ALTER TABLE products ADD FOREIGN KEY (product_group_id) REFERENCES
product_groups;

To add a not-null constraint, which cannot be written as a table constraint, use this syntax:
ALTER TABLE products ALTER COLUMN product_no SET NOT NULL;

The constraint will be checked immediately, so the table data must satisfy the constraint before it
can be added.

- Removing a Constraint

Then the command is:

Begum Durgahee 6
Labsheet02 PostgreSQL7.4

ALTER TABLE products DROP CONSTRAINT some_name;

To drop a not null constraint use

ALTER TABLE products ALTER COLUMN product_no DROP NOT NULL;

(Recall that not-null constraints do not have names.)

- Renaming a Column

To rename a column:
ALTER TABLE products RENAME COLUMN product_no TO product_number;

- Renaming a Table

To rename a table:
ALTER TABLE products RENAME TO items;

Subqueries

The following section will be based on the exercise given in Labsheet01b.

Now modify the tables in the exercise in Labsheet01b, such that:

EMP table: EMPNO is the primary key, ENAME is not null, DEPTNO is the foreign key.
PROJECT table: PNO is the primary key, PNAME is unique, PMGR is not null, BUDGET is
not null
DEPT table: DEPTNO is the primary key,

A query result can also be used in a condition of a where clause. In such a case the query is called
a subquery and the complete select statement is called a nested query.

A respective condition in the where clause then can have one of the following forms:
1. Set-valued subqueries
<expression> [not] in (<subquery>)
<expression> <comparison operator> [any|all] (<subquery>)
An <expression> can either be a column or a computed value.

2. Test for (non)existence


[not] exists (<subquery>)

Begum Durgahee 7
Labsheet02 PostgreSQL7.4

In a where clause conditions using subqueries can be combined arbitrarily by using the logical
connectives and and or.

Example: List the name and salary of employees of the department 20 who are leading
a project that started before December 31, 1990:

select ENAME, SAL from EMP


where EMPNO in
(select PMGR from PROJECT
where PSTART < ’31-DEC-90’)
and DEPTNO =20;

Explanation: The subquery retrieves the set of those employees who manage a project that
started before December 31, 1990. If the employee working in department 20 is contained in this
set (in operator), this tuple belongs to the query result set.

Example: List all employees who are working in a department located in BOSTON:

select _ from EMP


where DEPTNO in
(select DEPTNO from DEPT
where LOC = ’BOSTON’);

As long as the result of a subquery is not known in advance, i.e., whether it is a single value or a
set, it is advisable to use the in operator.

Example: List all those employees who are working in the same department as their
manager (note that components in [ ] are optional:

select _ from EMP E1


where DEPTNO in
(select DEPTNO from EMP [E]
where [E.]EMPNO = E1.MGR);

Explanation: The subquery in this example is related to its surrounding query since it refers to
the column E1.MGR. A tuple is selected from the table EMP (E1) for the query result if the value
for the column DEPTNO occurs in the set of values select in the subquery. One can think of the
evaluation of this query as follows: For each tuple in the table E1, the subquery is evaluated
individually. If the condition where DEPTNO in . . . evaluates to true, this tuple is selected.
Note that an alias for the table EMP in the subquery is not necessary since columns without a
preceding alias listed there always refer to the innermost query and tables.

• For the clause any, the condition evaluates to true if there exists at least on row selected
by the subquery for which the comparison holds. If the subquery yields an empty result
set, the condition is not satisfied.
• For the clause all, in contrast, the condition evaluates to true if for all rows selected by the
subquery the comparison holds. In this case the condition evaluates to true if the
subquery does not yield any row or value.

Example: Retrieve all employees who are working in department 10 and who earn at least as
much as any (i.e., at least one) employee working in department 30:

Begum Durgahee 8
Labsheet02 PostgreSQL7.4

select _ from EMP


where SAL >= any
(select SAL from EMP
where DEPTNO = 30)
and DEPTNO = 10;

For all and any, the following equivalences hold:


in ⇔ = any
not in ⇔ <> all or != all

Often a query result depends on whether certain rows do (not) exist in (other) tables. Such
type of queries is formulated using the exists operator.

Example: List all departments that have no employees:

select _ from DEPT


where not exists
(select _ from EMP
where DEPTNO = DEPT.DEPTNO);

Explanation: For each tuple from the table DEPT, the condition is checked whether there exists
a tuple in the table EMP that has the same department number (DEPT.DEPTNO). In case no such
tuple exists, the condition is satisfied for the tuple under consideration and it is selected. If
there exists a corresponding tuple in the table EMP, the tuple is not selected.

Begum Durgahee 9

Você também pode gostar