+ endterm="DATE97">. You should be aware that some language
+ features are extensions to the standard.
+
+
+ In the examples that follow, we assume that you have created a
+ database named mydb
, as described in the previous
+ chapter, and have started
psql.
+
+
+ Examples in this manual can also be found in source distribution
+ in the directory src/tutorial/. Refer to the
+ README file in that directory for how to use
+ them. To start the tutorial, do the following:
-Welcome to the POSTGRESQL interactive sql monitor:
- Please read the file COPYRIGHT for copyright terms of POSTGRESQL
-
- type \? for help on slash commands
- type \q to quit
- type \g or terminate with semicolon to execute query
- You are currently connected to the database: postgres
+...
+
+ The \i command reads in commands from the
+ specified files. The -s option puts you in
+ single step mode which pauses before sending a query to the
+ server. The commands used in this section are in the file
+ basics.sql.
+
+
+
+
+
Concepts
- The \i command read in queries from the specified
- files. The -s option puts you in single step mode which
- pauses before sending a query to the backend. Queries
- in this section are in the file basics.sql.
+
object-oriented database
+
+
PostgreSQL is a
relational
+ database management system (
RDBMS).
+ That means it is a system for managing data stored in
+ relations. Relation is essentially a
+ mathematical term for table. The notion of
+ storing data in tables is so commonplace today that it might
+ seem inherently obvious, but there are a number of other ways of
+ organizing databases. Files and directories on Unix-like
+ operating systems form an example of a hierarchical database. A
+ more modern development is the object-oriented database.
- has a variety of \d commands for showing system information.
- Consult these commands for more details;
- for a listing, type
\? at the
psql prompt.
+
+ Each table is a named collection of rows.
+ Each row has the same set of named columns,
+ and each column is of a specific data type. Whereas columns have
+ a fixed order in each row, it is important to remember that SQL
+ does not guarantee the order of the rows within the table in any
+ way (unless they are explicitly sorted).
-
-
-
-
Concepts
- The fundamental notion in
Postgres is
- that of a table, which is a named
- collection of rows. Each row has the same
- set of named columns, and each column is of
- a specific type. Furthermore, each row has a permanent
-
object identifier (
OID)
- that is unique throughout the database cluster. Historially,
- tables have been called classes in
-
Postgres, rows are object instances,
- and columns are attributes. This makes sense if you consider the
- object-relational aspects of the database system, but in this
- manual we will use the customary
SQL
- terminology. As previously discussed,
- tables are grouped into databases, and a collection of databases
- managed by a single
postmaster process
- constitutes a database cluster.
+
+ Tables are grouped into databases, and a collection of databases
+ managed by a single
PostgreSQL server
+ instance constitutes a database cluster.
-
+
+
Creating a New Table
+
+
+
You can create a new table by specifying the table
name, along with all column names and their types:
date date
);
+
+ You can enter this into psql with the line
+ breaks. psql will recognize that the command
+ is not terminated until the semicolon.
+
+
+ White space (i.e., spaces, tabs, and newlines) may be used freely
+ in SQL commands. That means you can type the command aligned
+ differently than above, or even all on one line. Two dashes
+ (--
) introduce comments.
+ Whatever follows them is ignored up to the end of the line. SQL
+ is also case insensitive about key words and identifiers, except
+ when identifiers are double-quoted to preserve the case (not done
+ above).
+
+
+ varchar(80) specifies a data type that can store
+ arbitrary character strings up to 80 characters in length.
+ int is the normal integer type. real is
+ a type for storing single precision floating point numbers.
+ date should be self-explanatory. (Yes, the column of
+ type date is also named date.
+ This may be convenient or confusing -- you choose.)
- Note that both keywords and identifiers are case-insensitive;
- identifiers can preserve case by surrounding them with
- double-quotes as allowed
- supports the usual
+
PostgreSQL supports the usual
- float, real, smallint,
-char(N),
- varchar(N), date, time,
- and timestamp, as well as other types of general utility and
- a rich set of geometric types. As we will
- see later,
Postgres can be customized
- with an
- arbitrary number of
- user-defined data types. Consequently, type names are
- not syntactical keywords, except where required to support special
- cases in the
SQL92 standard.
- CREATE command
- looks exactly like
- the command used to create a table in a traditional
- relational system. However, we will presently see that
- tables have properties that are extensions of the
- relational model.
+ smallint, real, double
+ precision, char(N>),
+ varchar(N>), date,
+ time, timestamp, and
+ interval as well as other types of general utility
+ and a rich set of geometric types.
+
PostgreSQL can be customized with an
+ arbitrary number of user-defined data types. Consequently, type
+ names are not syntactical keywords, except where required to
+ support special cases in the
SQL standard.
+
+
+ The second example will store cities and their associated
+ geographical location:
+CREATE TABLE cities (
+ name varchar(80),
+ location point
+);
+
+ The point type is such a
+
PostgreSQL-specific data type.
+
+
+
+
+
+ Finally, it should be mentioned that if you don't need a table any
+ longer or want to recreate it differently you can remove it using
+ the following command:
+
+DROP TABLE tablename;
+
-
-
Populating a Table with Rows
+
+
+
Populating a Table With Rows
+
+
+
The INSERT statement is used to populate a table with
INSERT INTO weather VALUES ('San Francisco', 46, 50, 0.25, '1994-11-27');
+
+ Note that all data types use rather obvious input formats. The
+ date column is actually quite flexible in what it
+ accepts, but for this tutorial we will stick to the unambiguous
+ format shown here.
- You can also use COPY to load large
- amounts of data from flat (
ASCII) files.
- This is usually faster because the data is read (or written) as a
- single atomic
- transaction directly to or from the target table. An example would be:
+ The point type requires a coordinate pair as input,
+ as shown here:
+INSERT INTO cities VALUES ('San Francisco', '(-194.0, 53.0)');
+
+
+ The syntax used so far requires you to remember the order of the
+ columns. An alternative syntax allows you to list the columns
+ explicitly:
-COPY weather FROM '/home/user/weather.txt' USING DELIMITERS '|';
+INSERT INTO weather (city, temp_lo, temp_hi, prcp, date)
+ VALUES ('San Francisco', 43, 57, 0.0, '1994-11-29');
+
+ You can also list the columns in a different order if you wish or
+ even omit some columns, e.g., unknown precipitation:
+INSERT INTO weather (date, city, temp_hi, temp_lo)
+ VALUES ('1994-11-29', 'Hayward', 54, 37);
+
+ Many developers consider explicitly listing the columns better
+ style than relying on the order implicitly.
+
+
+ Please enter all the commands shown above so you have some data to
+ work with in the following sections.
+
+
+
+
+
+ You could also have used COPY to load large
+ amounts of data from flat text files. This is usually faster
+ because the COPY is optimized for this
+ application while allowing less flexibility than
+ INSERT. An example would be:
+
+COPY weather FROM '/home/user/weather.txt';
where the path name for the source file must be available to the
- backend server
- machine, not the client, since the backend server reads the file directly.
+ backend server machine, not the client, since the backend server
+ reads the file directly. You can read more about the
+ COPY command in the Reference
+ Manual.
-
+
+
Querying a Table
- The weather table can be queried with normal relational
- selection and projection queries. A
SQL
- SELECT
- statement is used to do this. The statement is divided into
- a target list (the part that lists the columns to be
- returned) and a qualification (the part that specifies
- any restrictions). For example, to retrieve all the
- rows of weather, type:
+
+ To retrieve data from a table it is
+ SELECT statement is used to do this. The
+ statement is divided into a select list (the part that lists the
+ columns to be returned), a table list (the part that lists the
+ tables from which to retrieve the data), and an optional
+ qualification (the part that specifies any restrictions). For
+ example, to retrieve all the rows of
+ weather, type:
SELECT * FROM weather;
+ (where * means all columns
) and
+ the output should be:
+
+ city | temp_lo | temp_hi | prcp | date
+---------------+---------+---------+------+------------
+ San Francisco | 46 | 50 | 0.25 | 1994-11-27
+ San Francisco | 43 | 57 | 0 | 1994-11-29
+ Hayward | 37 | 54 | | 1994-11-29
+(3 rows)
+
+
- and the output should be:
-+--------------+---------+---------+------+------------+
-|city | temp_lo | temp_hi | prcp | date |
-+--------------+---------+---------+------+------------+
-|San Francisco | 46 | 50 | 0.25 | 1994-11-27 |
-+--------------+---------+---------+------+------------+
-|San Francisco | 43 | 57 | 0 | 1994-11-29 |
-+--------------+---------+---------+------+------------+
-|Hayward | 37 | 54 | | 1994-11-29 |
-+--------------+---------+---------+------+------------+
-
- You may specify any arbitrary expressions in the target list. For
+ You may specify any arbitrary expressions in the target list. For
example, you can do:
SELECT city, (temp_hi+temp_lo)/2 AS temp_avg, date FROM weather;
+ This should give:
+
+ city | temp_avg | date
+---------------+----------+------------
+ San Francisco | 48 | 1994-11-27
+ San Francisco | 50 | 1994-11-29
+ Hayward | 45 | 1994-11-29
+(3 rows)
+
+ Notice how the AS clause is used to relabel the
+ output column. (It is optional.)
- Arbitrary Boolean operators
- (AND, OR and
- NOT) are
- allowed in the qualification of any query. For example,
+ Arbitrary Boolean operators (AND,
+ OR, and NOT) are allowed in
+ the qualification of a query. For example, the following
+ retrieves the weather of San Francisco on rainy days:
SELECT * FROM weather
WHERE city = 'San Francisco'
AND prcp > 0.0;
-results in:
-+--------------+---------+---------+------+------------+
-|city | temp_lo | temp_hi | prcp | date |
-+--------------+---------+---------+------+------------+
-|San Francisco | 46 | 50 | 0.25 | 1994-11-27 |
-+--------------+---------+---------+------+------------+
-
+ Result:
+
+ city | temp_lo | temp_hi | prcp | date
+---------------+---------+---------+------+------------
+ San Francisco | 46 | 50 | 0.25 | 1994-11-27
+(1 row)
+
- As a final note, you can specify that the results of a
- select can be returned in a sorted order
- or with duplicate rows removed.
+
+ As a final note, you can request that the results of a select can
+ be returned in sorted order or with duplicate rows removed. (Just
+ to make sure the following won't confuse you,
+ DISTINCT and ORDER BY can be
+ used separately.)
SELECT DISTINCT city
FROM weather
ORDER BY city;
-
-
-
-
-
Redirecting SELECT Queries
-
- Any SELECT query can be redirected to a new table
-SELECT * INTO TABLE temp FROM weather;
-
-
- This forms an implicit CREATE command, creating a new
- table temp with the column names and types specified
- in the target list of the SELECT INTO command. We can
- then, of course, perform any operations on the resulting
- table that we can perform on other tables.
+
+ city
+---------------
+ Hayward
+ San Francisco
+(2 rows)
+
-
+
+
Joins Between Tables
+
+
+
- Thus far, our queries have only accessed one table at a
- time. Queries can access multiple tables at once, or
- access the same table in such a way that multiple
- rows of the table are being processed at the same
- time. A query that accesses multiple rows of the
- same or different tables at one time is called a join
- query.
- As an example, say we wish to find all the records that
- are in the temperature range of other records. In
- effect, we need to compare the temp_lo and temp_hi
- columns of each WEATHER row to the temp_lo and
- temp_hi columns of all other WEATHER columns.
+ Thus far, our queries have only accessed one table at a time.
+ Queries can access multiple tables at once, or access the same
+ table in such a way that multiple rows of the table are being
+ processed at the same time. A query that accesses multiple rows
+ of the same or different tables at one time is called a
+ join query. As an example, say you wish to
+ list all the weather records together with the location of the
+ associated city. In effect, we need to compare the city column of
+ each row of the weather table with the name column of all rows in
+ the cities table.
This is only a conceptual model. The actual join may
to the user.
-
- We can do this with the following query:
+ This would be accomplished by the following query:
-SELECT W1.city, W1.temp_lo AS low, W1.temp_hi AS high,
- W2.city, W2.temp_lo AS low, W2.temp_hi AS high
- FROM weather W1, weather W2
- WHERE W1.temp_lo < W2.temp_lo
- AND W1.temp_hi > W2.temp_hi;
+SELECT *
+ FROM weather, cities
+ WHERE city = name;
+
-+--------------+-----+------+---------------+-----+------+
-|city | low | high | city | low | high |
-+--------------+-----+------+---------------+-----+------+
-|San Francisco | 43 | 57 | San Francisco | 46 | 50 |
-+--------------+-----+------+---------------+-----+------+
-|San Francisco | 37 | 54 | San Francisco | 46 | 50 |
-+--------------+-----+------+---------------+-----+------+
-
+
+ city | temp_lo | temp_hi | prcp | date | name | location
+---------------+---------+---------+------+------------+---------------+-----------
+ San Francisco | 46 | 50 | 0.25 | 1994-11-27 | San Francisco | (-194,53)
+ San Francisco | 43 | 57 | 0 | 1994-11-29 | San Francisco | (-194,53)
+(2 rows)
+
-
- The semantics of such a join are
- that the qualification
- is a truth expression defined for the Cartesian product of
- the tables indicated in the query. For those rows in
- the Cartesian product for which the qualification is true,
-
Postgres computes and returns the
- values specified in the target list.
- does not assign any meaning to
- duplicate values in such expressions.
- This means that
Postgres
- sometimes recomputes the same target list several times;
- this frequently happens when Boolean expressions are connected
- with an "or". To remove such duplicates, you must use
- the SELECT DISTINCT statement.
-
-
- In this case, both W1 and
- W2 are surrogates for a
- row of the table weather, and both range over all
- rows of the table. (In the terminology of most
- database systems, W1 and W2
- are known as range variables.)
- A query can contain an arbitrary number of
- table names and surrogates.
+ Observe two things about the result set:
+
+
+ There is no result row for the city of Hayward. This is
+ because there is no matching entry in the
+ cities table for Hayward, so the join
+ cannot process the rows in the weather table. We will see
+ shortly how this can be fixed.
+
+
+
+
+ There are two columns containing the city name. This is
+ correct because the lists of columns of the
+ weather and the
+ cities tables are concatenated. In
+ practice this is undesirable, though, so you will probably want
+ to list the output columns explicitly rather than using
+ *:
+SELECT city, temp_lo, temp_hi, prcp, date, location
+ FROM weather, cities
+ WHERE city = name;
+
+
+
+
-
-
-
Updates
+
+
Exercise:
+
+ Attempt to find out the semantics of this query when the
+ WHERE clause is omitted.
+
+
- You can update existing rows using the
- UPDATE command.
- Suppose you discover the temperature readings are
- all off by 2 degrees as of Nov 28, you may update the
- data as follow:
+ Since the columns all had different names, the parser
+ automatically found out which table they belong to, but it is good
+ style to fully qualify column names in join queries:
-UPDATE weather
- SET temp_hi = temp_hi - 2, temp_lo = temp_lo - 2
- WHERE date > '1994-11-28';
+SELECT weather.city, weather.temp_lo, weather.temp_hi, weather.prcp, weather.date, cities.location
+ FROM weather, cities
+ WHERE cities.name = weather.city;
-
-
-
-
Deletions
- Deletions are performed using the DELETE command:
+ Join queries of the kind seen thus far can also be written in this
+ alternative form:
+
-DELETE FROM weather WHERE city = 'Hayward';
+SELECT *
+ FROM weather INNER JOIN cities ON (weather.city = cities.name);
- All weather recording belonging to Hayward are removed.
- One should be wary of queries of the form
+ This syntax is not as commonly used as the one above, but we show
+ it here to help you understand the following topics.
+
+
+
+ Now we will figure out how we can get the Hayward records back in.
+ What we want the query to do is to scan the
+ weather table and for each row to find the
+ matching cities row. If no matching row is
+ found we want some empty values
to be substituted
+ for the cities table's columns. This kind
+ of query is called an outer join. (The
+ joins we have seen to far are inner joins.) The command looks
+ like this:
+
-DELETE FROM tablename;
+SELECT *
+ FROM weather LEFT OUTER JOIN cities ON (weather.city = cities.name);
+
+ city | temp_lo | temp_hi | prcp | date | name | location
+---------------+---------+---------+------+------------+---------------+-----------
+ Hayward | 37 | 54 | | 1994-11-29 | |
+ San Francisco | 46 | 50 | 0.25 | 1994-11-27 | San Francisco | (-194,53)
+ San Francisco | 43 | 57 | 0 | 1994-11-29 | San Francisco | (-194,53)
+(3 rows)
- Without a qualification, DELETE will simply
- remove all rows from the given table, leaving it
- empty. The system will not request confirmation before
- doing this.
+ In particular, this query is a left outer
+ join because the table mentioned on the left of the
+ join operator will have each of its rows in the output at least
+ once, whereas the table on the right will only have those rows
+ output that match some row of the left table, and will have empty
+ values substituted appropriately.
+
+
+
+
Exercise:
+
+ There are also right outer joins and full outer joins. Try to
+ find out what those do.
+
+
+
+
aliasfor table name in query
+
+ We can also join a table against itself. This is called a
+ self join. As an example, suppose we wish
+ to find all the weather records that are in the temperature range
+ of other weather records. So we need to compare the
+ temp_lo> and temp_hi> columns of
+ each weather row to the
+ temp_lo and
+ temp_hi columns of all other
+ weather rows. We can do this with the
+ following query:
+
+SELECT W1.city, W1.temp_lo AS low, W1.temp_hi AS high,
+ W2.city, W2.temp_lo AS low, W2.temp_hi AS high
+ FROM weather W1, weather W2
+ WHERE W1.temp_lo < W2.temp_lo
+ AND W1.temp_hi > W2.temp_hi;
+
+ city | low | high | city | low | high
+---------------+-----+------+---------------+-----+------
+ San Francisco | 43 | 57 | San Francisco | 46 | 50
+ Hayward | 37 | 54 | San Francisco | 46 | 50
+(2 rows)
+
+
+ Here we have relabeled the weather table as W1> and
+ W2> to be able to distinguish the left and right side
+ of the join. You can also use these kinds of aliases in other
+ queries to save some typing, e.g.:
+SELECT *
+ FROM weather w, cities c
+ WHERE w.city = c.name;
+
+ You will encounter this style of abbreviating quite frequently.
-
-
Using Aggregate Functions
+
+
+
Aggregate Functions
+
+
+
+
Like most other relational database products,
aggregate functions.
min (minimum) over a set of rows.
- It is important to understand the interaction between aggregates and
- SQL's WHERE and HAVING clauses.
- The fundamental difference between WHERE and
- HAVING is this: WHERE selects
- input rows before groups and aggregates are computed (thus, it controls
- which rows go into the aggregate computation), whereas
- HAVING selects group rows after groups and
- aggregates are computed. Thus, the
- WHERE clause may not contain aggregate functions;
- it makes no sense to try to use an aggregate to determine which rows
- will be inputs to the aggregates. On the other hand,
- HAVING clauses always contain aggregate functions.
- (Strictly speaking, you are allowed to write a HAVING
- clause that doesn't use aggregates, but it's wasteful; the same condition
- could be used more efficiently at the WHERE stage.)
-
-
As an example, we can find the highest low-temperature reading anywhere
with
SELECT max(temp_lo) FROM weather;
-
+
+
+
+ max
+-----
+ 46
+(1 row)
+
+
+
If we want to know what city (or cities) that reading occurred in,
we might try
-SELECT city FROM weather WHERE temp_lo = max(temp_lo);
-
+SELECT city FROM weather WHERE temp_lo = max(temp_lo); WRONG
+
but this will not work since the aggregate
- max can't be used in
- <command>WHERE. However, as is often the case the query can be
- restated to accomplish the intended result; here by using a
- subselect:
+ max cannot be used in the
+ <literal>WHERE clause. However, as is often the case
+ the query can be restated to accomplish the intended result; here
+ by using a subquery:
SELECT city FROM weather
WHERE temp_lo = (SELECT max(temp_lo) FROM weather);
-
+
+
+
+ city
+---------------
+ San Francisco
+(1 row)
+
- This is OK because the sub-select is an independent computation that
- computes its own aggregate separately from what's happening in the outer
- select.
+ This is OK because the sub-select is an independent computation
+ that computes its own aggregate separately from what is happening
+ in the outer select.
- 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
+
+ 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
SELECT city, max(temp_lo)
FROM weather
GROUP BY city;
-
+
+
+
+ city | max
+---------------+-----
+ Hayward | 37
+ San Francisco | 46
+(2 rows)
+
which gives us one output row per city. We can filter these grouped
- rows using <command>HAVING>:
+ rows using <literal>HAVING>:
SELECT city, max(temp_lo)
FROM weather
GROUP BY city
- HAVING min(temp_lo) < 0;
-
+ HAVING max(temp_lo) < 40;
+
+
+
+ city | max
+---------+-----
+ Hayward | 37
+(1 row)
+
which gives us the same results for only the cities that have some
- below-zero readings. Finally, if we only care about cities whose
- names begin with "P", we might do
+ below-forty readings. Finally, if we only care about cities whose
+ names begin with S
, we might do
SELECT city, max(temp_lo)
FROM weather
- WHERE city like 'P%'
+ WHERE city LIKE 'S%'
GROUP BY city
- HAVING min(temp_lo) < 0;
-
+ HAVING max(temp_lo) < 40;
+
+
- Note that we can apply the city-name restriction in
- WHERE, since it needs no aggregate. This is
- more efficient than adding the restriction to HAVING,
+ It is important to understand the interaction between aggregates and
+ SQL's WHERE and HAVING clauses.
+ The fundamental difference between WHERE and
+ HAVING is this: WHERE selects
+ input rows before groups and aggregates are computed (thus, it controls
+ which rows go into the aggregate computation), whereas
+ HAVING selects group rows after groups and
+ aggregates are computed. Thus, the
+ WHERE clause must not contain aggregate functions;
+ it makes no sense to try to use an aggregate to determine which rows
+ will be inputs to the aggregates. On the other hand,
+ HAVING clauses always contain aggregate functions.
+ (Strictly speaking, you are allowed to write a HAVING
+ clause that doesn't use aggregates, but it's wasteful; the same condition
+ could be used more efficiently at the WHERE stage.)
+
+
+ Note that we can apply the city name restriction in
+ WHERE, since it needs no aggregate. This is
+ more efficient than adding the restriction to HAVING,
because we avoid doing the grouping and aggregate calculations
- for all rows that fail the WHERE check.
+ for all rows that fail the WHERE check.
+
+
+
+
+
+
Updates
+
+
+
+
+ You can update existing rows using the
+ UPDATE command.
+ Suppose you discover the temperature readings are
+ all off by 2 degrees as of November 28, you may update the
+ data as follow:
+
+UPDATE weather
+ SET temp_hi = temp_hi - 2, temp_lo = temp_lo - 2
+ WHERE date > '1994-11-28';
+
+
+
+ Look at the new state of the data:
+SELECT * FROM weather;
+
+ city | temp_lo | temp_hi | prcp | date
+---------------+---------+---------+------+------------
+ San Francisco | 46 | 50 | 0.25 | 1994-11-27
+ San Francisco | 41 | 55 | 0 | 1994-11-29
+ Hayward | 35 | 52 | | 1994-11-29
+(3 rows)
+
+
+
+
Deletions
+
+
+
+
+ Suppose you are no longer interested in the weather of Hayward,
+ then you can do the following to delete those rows from the table.
+ Deletions are performed using the DELETE
+ command:
+DELETE FROM weather WHERE city = 'Hayward';
+
+
+ All weather recording belonging to Hayward are removed.
+
+SELECT * FROM weather;
+
+
+
+ city | temp_lo | temp_hi | prcp | date
+---------------+---------+---------+------+------------
+ San Francisco | 46 | 50 | 0.25 | 1994-11-27
+ San Francisco | 41 | 55 | 0 | 1994-11-29
+(2 rows)
+
+
+
+ One should be wary of queries of the form
+
+DELETE FROM tablename;
+
+
+ Without a qualification, DELETE will simply
+ remove all rows from the given table, leaving it
+ empty. The system will not request confirmation before
+ doing this.
+
+
+
-
+ tutorial-start">
Getting Started
+
+
Installation
+
+ Before you can use
PostgreSQL you need
+ to install it, of course. It is possible that
+
PostgreSQL is already installed at your
+ site, either because it was included in your operating system
+ distribution or because the system administrator already installed
+ it. If that is the case, you should obtain information from the
+ operating system documentation or your system administrator about
+ how to access
PostgreSQL.
+
+
- How to begin work with
Postgres for a new user.
+ If you are not sure whether
PostgreSQL
+ is already available or whether you can use it for your
+ experimentation then you can install it yourself. Doing so is not
+ hard and it can be a good exercise.
+
PostgreSQL can be installed by any
+ unprivileged user, no superuser (root)
+ access is required.
-
-
- Some of the steps required to use
Postgres
- can be performed by any Postgres user, and some must be done by
- the site database administrator. This site administrator
- is the person who installed the software, created
- the database directories and started the
- process. This person does not have to be the Unix
- superuser ("root")
- or the computer system administrator; a person can install and use
-
Postgres without any special accounts or
- privileges.
-
-
- If you are installing
Postgres yourself, then
- refer to the Administrator's Guide for instructions on
- installation, and return
- to this guide when the installation is complete.
-
-
- Throughout this manual, any examples that begin with
- the character "%" are commands that should be typed
- at the Unix shell prompt. Examples that begin with the
- character "*" are commands in the Postgres query
- language, Postgres
SQL.
-
-
-
-
Setting Up Your Environment
- This section discusses how to set up
- your own environment so that you can use frontend
- applications. We assume
Postgres has
- already been
- successfully installed and started; refer to the Administrator's Guide
- and the installation notes
- for how to install Postgres.
+ If you are installing
PostgreSQL
+ yourself, then refer to the Administrator's
+ Guide for instructions on installation, and return to
+ this guide when the installation is complete. Be sure to follow
+ closely the section about setting up the appropriate environment
+ variables.
-
Postgres is a client/server
- application. As a user,
- you only need access to the client portions of the installation
- (an example
- of a client application is the interactive monitor
- For simplicity,
- we will assume that
Postgres has been
- installed in the
- directory /usr/local/pgsql. Therefore, wherever
- you see the directory /usr/local/pgsql you should
- substitute the name of the directory where
- actually installed.
- All
Postgres commands are installed in
- the directory
- /usr/local/pgsql/bin. Therefore, you should add
- this directory to your shell command path. If you use
- a variant of the Berkeley C shell, such as csh or tcsh,
- you would add
-
-% set path = ( /usr/local/pgsql/bin path )
-
-
- in the .login file in your home directory.
- If you use
- a variant of the Bourne shell, such as sh, ksh, or
- bash, then you would add
-
-% PATH=/usr/local/pgsql/bin:$PATH
-% export PATH
-
-
- to the .profile file in your home directory.
- From now on, we will assume that you have added the
-
Postgres bin directory to your path.
- In addition, we
- will make frequent reference to setting a shell
- variable or setting an environment
- variable throughout
- this document. If you did not fully understand the
- last paragraph on modifying your search path, you
- should consult the Unix manual pages that describe your
- shell before going any further.
+ If your site administrator has not set things up in the default
+ way, you may have some more work to do. For example, if the
+ database server machine is a remote machine, you will need to set
+ the PGHOST environment variable to the name of the
+ database server machine. The environment variable
+ PGPORT may also have to be set. The bottom line is
+ this: if you try to start an application program and it complains
+ that it cannot connect to the database, you should consult your
+ site administrator or, if that is you, the documentation to make
+ sure that your environment is properly set up. If you did not
+ understand the preceding paragraph then read the next section.
+
+
+
+
+
Architectural Fundamentals
- If your site administrator has not set things up in the
- default way, you may have some more work to do. For example, if
- the database
- server machine is a remote machine, you
- will need to set the
PGHOST environment
- variable to the name
- of the database server machine. The environment variable
-
PGPORT may also have to be set.
- The bottom line is this: if
- you try to start an application program and it complains
- that it cannot connect to the
postmaster,
- you should immediately consult your site administrator to make
- sure that your
- environment is properly set up.
+ Before we proceed, you should understand the basic
+
PostgreSQL system architecture.
+ Understanding how the parts of
+
PostgreSQL interact will make the next
+ chapter somewhat clearer.
+ In database jargon,
PostgreSQL uses a
+ client/server model. A
PostgreSQL
+ session consists of the following cooperating processes
+ (programs):
+
+
+
+ A server process, which manages the database files, accepts
+ connections to the database from client applications, and
+ performs actions on the database on behalf of the clients. The
+ database server program is called
+ postmaster.
+
+
+
+
+ The user's client (frontend) application that wants to perform
+ database operations. Client applications can be very diverse
+ in nature: They could be a text-oriented tool, a graphical
+ application, a web server that accesses the database to
+ display web pages, or a specialized database maintenance tool.
+ Some client applications are supplied with the
+
PostgreSQL distribution, most are
+ developed by users.
+
+
+
+
+
+
+ As is typical of client/server applications, the client and the
+ server can be on different hosts. In that case they communicate
+ over a TCP/IP network connection. You should keep this in mind,
+ because the files that can be accessed on a client machine might
+ not be accessible (or might only be accessed using a different
+ file name) on the database server machine.
+
+
+ The
PostgreSQL server can handle
+ multiple concurrent connections from clients. For that purpose it
+ starts (forks
) a new process for each connection.
+ From that point on, the client and the new server process
+ communicate without intervention by the original
+ postmaster process. Thus, the
+ postmaster is always running, waiting for
+ client connections, whereas client and associated server processes
+ come and go. (All of this is of course invisible to the user. We
+ only mention it here for completeness.)
+
-
-
Starting the Interactive Monitor (psql)
+
+
+
Creating a Database
+
+
+ creating
+
+
+
+
- Assuming that your site administrator has properly
- started the
postmaster process and
- authorized you to
- use the database, you (as a user) may begin to start up
- applications. As previously mentioned, you should add
- /usr/local/pgsql/bin to your shell search path.
- In most cases, this is all you should have to do in
- terms of preparation.
+ The first test to see whether you can access the database server
+ is to try to create a database. A running
+
PostgreSQL server can manage many
+ databases. Typically, a separate database is used for each
+ project or for each user.
- Two different styles of connections
- are supported. The site administrator will have chosen to allow
- TCP/IP network connections
- or will have restricted database access to local (same-machine)
- socket connections only.
- These choices become significant if you encounter problems in
- connecting to a database, since you will want to confirm that you
- are choosing an allowed connection option.
+ Possibly, your site administrator has already created a database
+ for your use. He should have told you what the name of your
+ database is. In this case you can omit this step and skip ahead
+ to the next section.
- If you get the following error message from a
- command (such as
psql or
+ To create a new database, in this example named
+ mydb
, you use the following command:
+
+
+ This should produce as response:
+
+CREATE DATABASE
+
+ Is so, this step was successful and you can skip over the
+ remainder of this section.
+
-% psql template1
+ If you see a message similar to
+
+createdb: command not found
+
+ then PostgreSQL was not installed properly. Either it was not
+ installed at all or the search path was not set correctly. Try
+ calling the command with an absolute path instead:
+
+
$ /usr/local/pgsql/bin/createdb
+
+ The path at your site might be different. Contact your site
+ administrator or check back in the installation instructions to
+ correct the situation.
+
+
+ Another response could be this:
+
psql: could not connect to server: Connection refused
Is the server running locally and accepting
connections on Unix domain socket "/tmp/.s.PGSQL.5432"?
-
+createdb: database creation failed
+
+ This means that the server was not started, or it was not started
+ where createdb expected it. Again, check the
+ installation instructions or consult the administrator.
+
- or
+ If you do not have the privileges required to create a database,
+ you will see the following:
+
+ERROR: CREATE DATABASE: permission denied
+createdb: database creation failed
+
+ Not every user has authorization to create new databases. If
+
PostgreSQL refuses to create databases
+ for you then the site administrator needs to grant you permission
+ to create databases. Consult your site administrator if this
+ occurs. If you installed
PostgreSQL
+ yourself then you should log in for the purposes of this tutorial
+ under the user account that you started the server as.
+
+
+ As an explanation for why this works:
+
PostgreSQL user names are separate
+ from operating system user accounts. If you connect to a
+ database, you can choose what
+
PostgreSQL user name to connect as;
+ if you don't, it will default to the same name as your current
+ operating system account. As it happens, there will always be a
+
PostgreSQL user account that has the
+ same name as the operating system user that started the server,
+ and it also happens that that user always has permission to
+ create databases. Instead of logging in as that user you can
+ also specify the option everywhere to select
+ a
PostgreSQL user name to connect as.
+
+
+
+
+ You can also create databases with other names.
+
PostgreSQL allows you to create any
+ number of databases at a given site. Database names must have an
+ alphabetic first character and are limited to 32 characters in
+ length. A convenient choice is to create a database with the same
+ name as your current user name. Many tools assume that database
+ name as the default, so it can save you some typing. To create
+ that database, simply type
+
+
+
+
+ If you don't want to use your database anymore you can remove it.
+ For example, if you are the owner (creator) of the database
+ mydb
, you can destroy it using the following
+ command:
+
+
+ (In this case, the database name does not default to the user
+ account name. You always need to specify it.) This action
+ physically removes all files associated with the database and
+ cannot be undone, so this should only be done with a great deal of
+ forethought.
+
+
-% psql -h localhost template1
-psql: could not connect to server: Connection refused
- Is the server running on host localhost and accepting
- TCP/IP connections on port 5432?
-
- it is usually because
+
+
Accessing a Database
+
+
+
+
+ Once you have created a database, you can access it by:
+
+
+
+ Running the
PostgreSQL interactive
+ terminal program, called psql
, which allows you
+ to interactively enter, edit, and execute
+
+
-
- the
postmaster is not running,
- or
+ Using an existing graphical frontend tool like
+
ODBC) to create and manipulate a database.
+ These possibilities are not covered in this tutorial.
- you are attempting to connect to the wrong server host.
+ Writing a custom application, using one of the several
+ available language bindings. These possibilities are discussed
+ further in The PostgreSQL Programmer's
+ Guide.
+
+ You probably want to start up psql, to try out
+ the examples in this tutorial. It can be activated for the
+ mydb
database by typing the command:
+
+
+ If you leave off the database name then it will default to your
+ user account name. You already discovered this scheme in the
+ previous section.
- If you get the following error message:
-
-FATAL 1:Feb 17 23:19:55:process userid (2360) != database owner (268)
-
-
- it means that the site administrator started the
- as the wrong user. Tell him to restart it as
- the
Postgres superuser.
+ In psql, you will be greeted with the following
+ message:
+
+Welcome to psql, the PostgreSQL interactive terminal.
+
+Type: \copyright for distribution terms
+ \h for help with SQL commands
+ \? for help on internal slash commands
+ \g or terminate with semicolon to execute query
+ \q to quit
+
+mydb=>
+
+ The last line could also be
+
+mydb=#
+
+ That would mean you are a database superuser, which is most likely
+ the case if you installed
PostgreSQL
+ yourself. Being a superuser means that you are not subject to
+ access controls. For the purpose of this tutorial this is not of
+ importance.
-
-
-
Managing a Database
+ If you have encountered problems starting psql
+ then go back to the previous section. The diagnostics of
+ psql and createdb are
+ similar, and if the latter worked the former should work as well.
+
- Now that
Postgres is up and running we
- can create some
- databases to experiment with. Here, we describe the
- basic commands for managing a database.
+ The last line printed out by psql is the
+ prompt, and it indicates that psql is listening
+ to you and that you can type
SQL queries into a
+ workspace maintained by psql. Try out these
+ commands:
+
+
mydb=> SELECT version();
+ version
+----------------------------------------------------------------
+ PostgreSQL 7.2devel on i586-pc-linux-gnu, compiled by GCC 2.96
+(1 row)
+
+
mydb=> SELECT current_date;
+ date
+------------
+ 2001-08-31
+(1 row)
+
+ ?column?
+----------
+ 4
+(1 row)
+
- applications assume that the database name, if not specified, is
- the same as the name on your computer
- account.
+ The psql program has a number of internal
+ commands that are not SQL commands. They begin the backslash
+ character, \
. Some of these
+ commands were already listed in the welcome message. For example,
+ you can get help on the syntax of various
+ commands by typing:
+
+
- If your database administrator has set up your account without
- database creation privileges,
- then she should have told you what the name of your database is. If
- this is the case, then you
- can skip the sections on creating and destroying databases.
+ To get out of psql, type
+
+
+ and psql will quit and return you to your
+ command shell. (For more internal commands, type
+ \? at the psql prompt.) The
+ full capabilities of psql are documented in the
+ Reference Manual. If PostgreSQL is
+ installed correctly you can also type man psql
+ at the operating system shell prompt to see the documentation. In
+ this tutorial we will not use these features explicitly, but you
+ can use them yourself when you see it fit.
-
-
Creating a Database
-
- Let's say you want to create a database named
- mydb.
- You can do this with the following command:
-% createdb mydb
-
-
-
- If you do not have the privileges required to create a database,
- you will see
- the following:
-% createdb mydb
-NOTICE:user "your username" is not allowed to create/destroy databases
-createdb: database creation failed on mydb.
-
-
-
-
Postgres allows you to create any
- number of databases
- at a given site and you automatically become the
- database administrator of the database you just created.
- Database names must have an alphabetic first
- character and are limited to 32 characters in length.
- Not every user has authorization to become a database
- administrator. If
Postgres refuses to
- create databases
- for you, then the site administrator needs to grant you
- permission to create databases. Consult your site
- administrator if this occurs.
-
-
-
-
-
Accessing a Database
-
- Once you have constructed a database, you can access it
- by:
-
-
-
- Running the
Postgres terminal
- monitor programs
- (e.g.
psql) which allows you to
- interactively
- enter, edit, and execute
SQL commands.
-
-
-
-
- Using an existing native frontend tool like
-
ODBC) to create and manipulate a
- database.
-
-
-
-
- Using a language like perl or tcl which has a supported
- interface for
Postgres. Some of
- these languages also have convenient and powerful GUI toolkits
- which can help you construct custom
- applications.
pgaccess, mentioned
- above, is one such application written in tk/tcl and can be
- used as an example.
-
-
-
-
- Writing a
C program using
- the LIBPQ subroutine
- library. This allows you to submit
- from
C and get answers and
- status messages back to
- your program. This interface is discussed further
- in The PostgreSQL Programmer's Guide.
-
-
-
-
- You might want to start up
psql,
- to try out the examples in this manual.
- It can be activated for the mydb
- database by typing the command:
-% psql mydb
-
-
- You will be greeted with the following message:
-Welcome to the POSTGRESQL interactive sql monitor:
- Please read the file COPYRIGHT for copyright terms of POSTGRESQL
-
- type \? for help on slash commands
- type \q to quit
- type \g or terminate with semicolon to execute query
- You are currently connected to the database: template1
-
-mydb=>
-
-
-
- This prompt indicates that the terminal monitor is listening
- to you and that you can type
SQL queries into a
- workspace maintained by the terminal monitor.
- The
psql program responds to escape
- codes that begin
- with the backslash character, "\" For example, you
- can get help on the syntax of various
- commands by typing:
-mydb=> \h
-
-
-
- Once you have finished entering your queries into the
- workspace, you can pass the contents of the workspace
- to the
Postgres server by typing:
-mydb=> \g
-
-
- This tells the server to process the query. If you
- terminate your query with a semicolon, the "\g" is not
- necessary.
-
psql will automatically process
- semicolon terminated queries.
- To read queries from a file, say myFile, instead of
- entering them interactively, type:
-mydb=> \i fileName
-
-
- To get out of
psql and return to Unix, type
-mydb=> \q
-
-
- and
psql will quit and return
- you to your command
- shell. (For more escape codes, type \h at the
- monitor prompt.)
- White space (i.e., spaces, tabs and newlines) may be
- used freely in
SQL queries. Single-line
- comments are denoted by
- "--". Everything after the dashes up to the end of the
- line is ignored. Multiple-line comments, and comments within a line,
- are denoted by "/* ... */".
-
-
-
-
-
Destroying a Database
-
- If you are the database administrator for the database
- mydb, you can destroy it using the
- following Unix command:
-% dropdb mydb
-
- This action physically removes all of the Unix files
- associated with the database and cannot be undone, so
- this should only be done with a great deal of forethought.
-
-
-
&legal;
+
Welcome
+
+ Welcome to
PostgreSQL and the
+ PostgreSQL Tutorial. The following few
+ chapters are intended to give a simple introduction to
+
PostgreSQL, relational database
+ concepts, and the SQL language to those who are new to any one of
+ these aspects. We only assume some general knowledge about how to
+ use computers. No particular Unix or programming experience is
+ required.
+
+
+ After you have worked through this tutorial you might want to move on
+ to reading the User's
+ Guide]]>]]> to
+ gain a more formal knowledge of the SQL language, or the
+ Programmer's
+ Guide]]>]]>
+ for information about developing applications for
+
+
+ We hope you have a pleasant experience with
+
+
+
&intro;
]]>
- &sql;
- &arch;
&start;
&query;
&advanced;
&biblio;
+ &bookindex;
]]>
---------------------------------------------------------------------------
--
-- advanced.sql-
--- more POSTGRES SQL features. (These are not part of the SQL-92
--- standard.)
+-- Tutorial on advanced more PostgreSQL features
--
--
-- Copyright (c) 1994, Regents of the University of California
--
--- $Id: advanced.source,v 1.3 1999/07/08 15:28:51 momjian Exp $
+-- $Id: advanced.source,v 1.4 2001/09/02 23:27:50 petere Exp $
--
---------------------------------------------------------------------------
-----------------------------
-- Inheritance:
--- a table can inherit from zero or more tables. A query can reference
+-- S table can inherit from zero or more tables. A query can reference
-- either all rows of a table or all rows of a table plus all of its
-- descendants.
-----------------------------
state char(2)
) INHERITS (cities);
--- now, let's populate the tables
+-- Now, let's populate the tables.
INSERT INTO cities VALUES ('San Francisco', 7.24E+5, 63);
INSERT INTO cities VALUES ('Las Vegas', 2.583E+5, 2174);
INSERT INTO cities VALUES ('Mariposa', 1200, 1953);
WHERE c.altitude > 500;
------------------------------
--- Time Travel:
--- this feature allows you to run historical queries.
--- removed for v6.3, but possible using triggers.
--- see contrib/spi/README for more information.
------------------------------
-
--- first, let's make some changes to the cities table (suppose Mariposa's
--- population grows 10% this year)
-
--- UPDATE cities
--- SET population = population * 1.1
--- WHERE name = 'Mariposa';
-
--- the default time is the current time ('now'):
-
--- SELECT * FROM cities WHERE name = 'Mariposa';
-
--- we can also retrieve the population of Mariposa ever has. ('epoch' is the
--- earliest time representable by the system)
-
--- SELECT name, population
--- FROM cities['epoch', 'now'] -- can be abbreviated to cities[,]
--- WHERE name = 'Mariposa';
-
-
-----------------------
--- Arrays:
--- attributes can be arrays of base types or user-defined types
-----------------------
-
-CREATE TABLE sal_emp (
- name text,
- pay_by_quarter int4[],
- schedule text[][]
-);
-
--- insert instances with array attributes. Note the use of braces
-
-INSERT INTO sal_emp VALUES (
- 'Bill',
- '{10000,10000,10000,10000}',
- '{{"meeting", "lunch"}, {}}');
-
-INSERT INTO sal_emp VALUES (
- 'Carol',
- '{20000,25000,25000,25000}',
- '{{"talk", "consult"}, {"meeting"}}');
-
-----------------------
--- queries on array attributes
-----------------------
-SELECT name FROM sal_emp WHERE
- sal_emp.pay_by_quarter[1] <> sal_emp.pay_by_quarter[2];
-
--- retrieve third quarter pay of all employees
-
-SELECT sal_emp.pay_by_quarter[3] FROM sal_emp;
-
--- select subarrays
-
-SELECT sal_emp.schedule[1:2][1:1] FROM sal_emp WHERE
- sal_emp.name = 'Bill';
-
-
-- clean up (you must remove the children first)
-DROP TABLE sal_emp;
DROP TABLE capitals;
DROP TABLE cities;
--
-- Copyright (c) 1994, Andrew Yu, University of California
--
--- $Id: basics.source,v 1.3 1999/07/08 15:27:01 momjian Exp $
+-- $Id: basics.source,v 1.4 2001/09/02 23:27:50 petere Exp $
--
---------------------------------------------------------------------------
-----------------------------
--- Creating a table:
--- a CREATE TABLE is used to create base tables. POSTGRES SQL has
--- its own set of built-in types. (Note that keywords are case-
--- insensitive but identifiers are case-sensitive.)
+-- Creating a New Table:
+-- A CREATE TABLE is used to create base tables. PostgreSQL has
+-- its own set of built-in types. (Note that SQL is case-
+-- insensitive.)
-----------------------------
CREATE TABLE weather (
city varchar(80),
temp_lo int, -- low temperature
temp_hi int, -- high temperature
- prcp float8, -- precipitation
+ prcp real, -- precipitation
date date
);
location point
);
+
-----------------------------
--- Inserting data:
--- an INSERT statement is used to insert a new row into a table. There
+-- Populating a Table With Rows:
+-- An INSERT statement is used to insert a new row into a table. There
-- are several ways you can specify what columns the data should go to.
-----------------------------
--- 1. the simplest case is when the list of value correspond to the order of
+-- 1. The simplest case is when the list of value correspond to the order of
-- the columns specified in CREATE TABLE.
INSERT INTO weather
- VALUES ('San Francisco', 46, 50, 0.25, '11/27/1994');
+ VALUES ('San Francisco', 46, 50, 0.25, '1994-11-27');
INSERT INTO cities
- VALUES ('San Francisco', '(-194.0, 53.0)');
+ VALUES ('San Francisco', '(-194.0, 53.0)');
--- 2. you can also specify what column the values correspond to. (The columns
--- can be specified in any order. You may also omit any number of columns.
--- eg. unknown precipitation below)
+-- 2. You can also specify what column the values correspond to. (The columns
+-- can be specified in any order. You may also omit any number of columns,
+-- e.g., unknown precipitation below.
INSERT INTO weather (city, temp_lo, temp_hi, prcp, date)
- VALUES ('San Francisco', 43, 57, 0.0, '11/29/1994');
+ VALUES ('San Francisco', 43, 57, 0.0, '1994-11-29');
INSERT INTO weather (date, city, temp_hi, temp_lo)
- VALUES ('11/29/1994', 'Hayward', 54, 37);
+ VALUES ('1994-11-29', 'Hayward', 54, 37);
-----------------------------
--- Retrieving data:
--- a SELECT statement is used for retrieving data. The basic syntax is
--- SELECT columns FROM tables WHERE predicates
+-- Querying a Table:
+-- A SELECT statement is used for retrieving data. The basic syntax is
+-- SELECT columns FROM tables WHERE predicates.
-----------------------------
--- a simple one would be
+-- A simple one would be:
SELECT * FROM weather;
--- you may also specify expressions in the target list (the 'AS column'
--- specifies the column name of the result. It is optional.)
+-- You may also specify expressions in the target list. (The 'AS column'
+-- specifies the column name of the result. It is optional.)
SELECT city, (temp_hi+temp_lo)/2 AS temp_avg, date FROM weather;
--- if you want to retrieve rows that satisfy certain condition (ie. a
--- restriction), specify the condition in WHERE. The following retrieves
+-- If you want to retrieve rows that satisfy certain condition (i.e., a
+-- restriction), specify the condition in WHERE. The following retrieves
-- the weather of San Francisco on rainy days.
SELECT *
-FROM weather
-WHERE city = 'San Francisco'
- and prcp > 0.0;
+ FROM weather
+ WHERE city = 'San Francisco'
+ AND prcp > 0.0;
--- here is a more complicated one. Duplicates are removed when DISTINCT is
--- specified. ORDER BY specifies the column to sort on. (Just to make sure the
+-- Here is a more complicated one. Duplicates are removed when DISTINCT is
+-- specified. ORDER BY specifies the column to sort on. (Just to make sure the
-- following won't confuse you, DISTINCT and ORDER BY can be used separately.)
SELECT DISTINCT city
-FROM weather
-ORDER BY city;
+ FROM weather
+ ORDER BY city;
+
-----------------------------
--- Retrieving data into other classes:
--- a SELECT ... INTO statement can be used to retrieve data into
--- another class.
+-- Joins Between Tables:
+-- queries can access multiple tables at once or access the same table
+-- in such a way that multiple instances of the table are being processed
+-- at the same time.
-----------------------------
-SELECT * INTO TABLE mytemp
-FROM weather
-WHERE city = 'San Francisco'
- and prcp > 0.0;
+-- The following joins the weather table and the cities table.
-SELECT * from mytemp;
+SELECT *
+ FROM weather, cities
+ WHERE city = name;
------------------------------
--- Aggregates
------------------------------
+-- This prevents a duplicate city name column:
-SELECT max(temp_lo)
-FROM weather;
+SELECT city, temp_lo, temp_hi, prcp, date, location
+ FROM weather, cities
+ WHERE city = name;
--- Aggregate with GROUP BY
-SELECT city, max(temp_lo)
-FROM weather
-GROUP BY city;
+-- since the column names are all different, we don't have to specify the
+-- table name. If you want to be clear, you can do the following. They give
+-- identical results, of course.
------------------------------
--- Joining tables:
--- queries can access multiple tables at once or access the same table
--- in such a way that multiple instances of the table are being processed
--- at the same time.
------------------------------
+SELECT weather.city, weather.temp_lo, weather.temp_hi, weather.prcp, weather.date, cities.location
+ FROM weather, cities
+ WHERE cities.name = weather.city;
--- suppose we want to find all the records that are in the temperature range
--- of other records. W1 and W2 are aliases for weather.
+-- JOIN syntax
+
+SELECT *
+ FROM weather JOIN cities ON (weather.city = cities.name);
+
+-- Outer join
+
+SELECT *
+ FROM weather LEFT OUTER JOIN cities ON (weather.city = cities.name);
+
+-- Suppose we want to find all the records that are in the temperature range
+-- of other records. W1 and W2 are aliases for weather.
SELECT W1.city, W1.temp_lo, W1.temp_hi,
W2.city, W2.temp_lo, W2.temp_hi
WHERE W1.temp_lo < W2.temp_lo
and W1.temp_hi > W2.temp_hi;
--- let's join two tables. The following joins the weather table
--- and the cities table.
-SELECT city, location, prcp, date
-FROM weather, cities
-WHERE name = city;
+-----------------------------
+-- Aggregate Functions
+-----------------------------
--- since the column names are all different, we don't have to specify the
--- table name. If you want to be clear, you can do the following. They give
--- identical results, of course.
+SELECT max(temp_lo)
+ FROM weather;
+
+SELECT city FROM weather
+ WHERE temp_lo = (SELECT max(temp_lo) FROM weather);
+
+-- Aggregate with GROUP BY
+SELECT city, max(temp_lo)
+ FROM weather
+ GROUP BY city;
+
+-- ... and HAVING
+SELECT city, max(temp_lo)
+ FROM weather
+ GROUP BY city
+ HAVING max(temp_lo) < 40;
-SELECT w.city, c.location, w.prcp, w.date
-FROM weather w, cities c
-WHERE c.name = w.city;
-----------------------------
--- Updating data:
--- an UPDATE statement is used for updating data.
+-- Updates:
+-- An UPDATE statement is used for updating data.
-----------------------------
--- suppose you discover the temperature readings are all off by 2 degrees as
+-- Suppose you discover the temperature readings are all off by 2 degrees as
-- of Nov 28, you may update the data as follow:
UPDATE weather
- SET temp_hi = temp_hi - 2, temp_lo = temp_lo - 2
- WHERE date > '11/28/1994';
+ SET temp_hi = temp_hi - 2, temp_lo = temp_lo - 2
+ WHERE date > '1994-11-28';
-SELECT * from weather;
+SELECT * FROM weather;
-----------------------------
--- Deleting data:
--- a DELETE statement is used for deleting rows from a table.
+-- Deletions:
+-- A DELETE statement is used for deleting rows from a table.
-----------------------------
--- suppose you are no longer interested in the weather of Hayward, you can
--- do the following to delete those rows from the table
+-- Suppose you are no longer interested in the weather of Hayward, then you can
+-- do the following to delete those rows from the table.
DELETE FROM weather WHERE city = 'Hayward';
-SELECT * from weather;
+SELECT * FROM weather;
--- you can also delete all the rows in a table by doing the following. (This
+-- You can also delete all the rows in a table by doing the following. (This
-- is different from DROP TABLE which removes the table in addition to the
-- removing the rows.)
DELETE FROM weather;
-SELECT * from weather;
+SELECT * FROM weather;
+
-----------------------------
-- Removing the tables:
--- DROP TABLE is used to remove tables. After you have done this, you
+-- DROP TABLE is used to remove tables. After you have done this, you
-- can no longer use those tables.
-----------------------------
-DROP TABLE weather, cities, mytemp;
+DROP TABLE weather, cities;