Sunteți pe pagina 1din 46

c




„  



    

CHARACTER(n)’ CHARACTER VARYING(n)’  TEXT
Six numeric data types SMALLINT’ INTEGER’ BIGINT’ NUMERIC(p,s)  
 

REAL’ DOUBLE PRECISION


  




    

CHARACTER(n)’ CHARACTER VARYING(n)’  TEXT
Six numeric data types SMALLINT’ INTEGER’ BIGINT’ NUMERIC(p,s)  
 

REAL’ DOUBLE PRECISION

A value of type CHARACTER(n) can hold a fixed-length string of n characters. If you store a value that is shorter
than n, the value is padded with spaces to increase the length to exactly n characters. You can abbreviate
CHARACTER(n) to CHAR(n). If you omit the "(n) " when you create a CHARACTER column, the length is
assumed to be 1.
The CHARACTER VARYING(n) type defines a variable-length string of at most n characters. VARCHAR(n) is a
synonym for CHARACTER VARYING(n). If you omit the "(n) " when creating a CHARACTER VARYING
column, you can store strings of any length in that column.
The last string type is TEXT. A TEXT column is equivalent to a VARCHAR column without a specified lengtha
TEXT column can store strings of any length.

| 
     
A string value is a sequence of characters surrounded by a pair of delimiters. Prior to PostgreSQL version 8.0, you
had to use a pair of single quote characters to delimit a string value. Starting with version 8.0, you can also define
your own delimiters for each string value using a form known as dollar quoting. Each of the following is a valid
string value:
rI am a stringr
r r
rr

You can also write these same string values using dollar quoting as follows:
$$I am a string$$
$$ $$
$$$$

An empty string is not the same as a NULL value. An empty string means that you have a known value that just
happens to be empty, whereas NULL implies that the value is unknown. An empty string means that you do have
the information, but it just happens to be empty.
å

An escape is a special character that tells PostgreSQL that the character (or characters) following the escape is to be
interpreted as a directive instead of as a literal value. In PostgreSQL, the escape character is the backslash (\).
"Where's my car?" could be entered as:
r ererrs my car?r
r ere\rs my car?r
$$ erers my car?$$
r ere\0
s my car?r


To summarize, here are the four ways that you can embed a single quote within a string:
rItrrs rig t w ere you left itr
rIt\rs rig t w ere you left itr
rIt\0
s rig t w ere you left itr
$$Itrs rig t w ere you left it$$

When PostgreSQL sees a backslash in a string literal, it discards the backslash and interprets the following
characters according to the following rules:
\b is t e backspace c aracter
\f is t e form feed c aracter
\r is t e carriage-return c aracter
\n is t e newline c aracter
\t is t e tab c aracter

|  


The concatenation operator (´´) is used to combine two string values into a single TEXT value. For example, the
expression

rT is is r ´´ rone stringr

will evaluate to the value: rT is is one stringr. And the expression


rT e current time is r ´´ now()

will evaluate to a TEXT value such as,

rT e current time is 00-0-0   


-0r.

‘
‘‘
‘
 ‘

 Ô
Expression < <= = <> >= >
rstringr Ô rstringr ALSE trUE trUE ALSE trUE ALSE
‰

‘
‘‘
‘
 ‘

 Ô
rstringr Ô rstringr ALSE ALSE ALSE trUE TRUE trUE

rStringr Ô rstringr trUE trUE ALSE trUE ALSE ALSE


____________________


 
  
There are two important operators that you should know about before we go much furtheractually it's one operator,
but you can write it two different ways.
The CAST() operator is used to convert a value from one data type to another. There are two ways to write the
CAST() operator:

CAST(expression AS type)
expression type


expression 

  


 

For example, the expression CAST( 'abc ' AS INTEGER ) results in an error (specifically, 'pg_atoi error
in "abc" canrt parse "abc" ') because rabcr obviously can't be converted into an integer.

When you convert between related data types, you may gain or lose precision. For example, when you convert from
a fractional numeric type into an integer type, the value is rounded:

SELECT CAST( CAST(  


AS LOAT8 ) AS INTEGER );
----------
 

î    
PostgreSQL provides a variety of numeric data types. Of the six numeric types, four are exact (SMALLINT,
INTEGER, BIGINT, NUMERIC(p,s)) and two are approximate (REAL, DOUBLE PRECISION).
Three of the four exact numeric types (SMALLINT, INTEGER, and BIGINT) can store only integer values. The
fourth (NUMERIC(p,s)) can accurately store any value that fits within the specified number (p) of digits. A
NUMERIC column, obviously, holds numeric values. When you create a NUMERIC column, you have to tell
PostgreSQL the total number of digits that you want to store and the number of fractional digits (that is, the number
of digits to the right of the decimal point).

The approximate numeric types, on the other hand, cannot store all values exactly. Instead, an approximate data
type stores an approximation of a real number. The DOUBLE PRECISION type, for example, can store a total of
15 significant digits, but when you perform calculations using a DOUBLE PRECISION value, you can run into
rounding errors.
 

|
  

    

The four exact data types can accurately store any value within a type-specific range.

‘ ‘
‘ ‘ ‘
Y    |
 
   

    
   
SMALLINT 2 -32768 +32767
INTEGER 4 -2147483648 +2147483647
BIGINT 8 -9223372036854775808 +9223372036854775807
NUMERIC(p,s) 11+(p/2) No limit No limit

The NUMERIC(p,s) data type can accurately store any number that fits within the specified number of digits.
When you create a column of type NUMERIC(p,s), you can specify the total number of decimal digits (p) and the
number of fractional digits (s). The total number of decimal digits is called the precision, and the number of
fractional digits is called the scale.
‘
‘
‘
  ‘
‘ ‘ ‘
Y    |
 
    
REAL 4 6 decimal digits
DOUBLE PRECISION 8 15 decimal digits

‘ 
 ‘‘
‘
‘ ‘ ‘
  |  
SMALLINT INT
INTEGER INT, INT
BIGINT INT8
NUMERIC(p,s) DECIMAL(p,s)
REAL LOAT, LOAT
DOUBLE PRECISION LOAT8
·

| 
     

6ere are some examples of valid fractional literals:

0e+
0e-
e0

A numeric literal that contains only digits is considered to be an integer literal. 6ere are some examples of valid
integer literals:

-00
0 

0 8

80

-
0 8

808

A fractional literal is always considered to be of type DOUBLE PRECISION. An integer literal is considered to be
of type INTEGER, unless the value is too large to fit into an integerin which case, it will be promoted first to type
BIGINT, then to NUMERIC or REAL if necessary.

 


The -- characters introduce a commentary text that follows is ignored.

„    


PostgreSQL supports four basic temporal data types plus a couple of extensions that deal with time zone issues.
The DATE type is used to store dates. A DATE value stores a century, year, month, and day.
The TIME data type is used to store a time-of-day value. A TIME value stores hours, minutes, seconds, and
microseconds.
The TIMESTAMP data type combines a DATE and a TIME, storing a century, year, month, day, hour, minutes,
seconds, and microseconds (TIMESTAMP column gives you both date and time components, centuries through
microseconds.). Unlike the TIME data type, a TIMESTAMP does include a time zone. If, for some reason, you want
a date/time value that does not include a time zone, you can use the type TIMESTAMP ITHOUT TIME ZONE.
The last temporal data type is the INTERVAL. An INTERVAL represents a span of time. I find that the easiest way
to think about INTERVAL values is to remember that an INTERVAL stores some (possibly large) number of
seconds, but you can group the seconds into larger units for convenience. For example, the CAST( r weekr
AS INTERVAL ) is equal to CAST( r0800 secondsr AS INTERVAL ), which is equal to CAST( r

daysr AS INTERVAL ) you can use whichever format you find easiest to work with.

select CAST( r weekr AS INTERVAL )


‘ "
days"

select CAST( r0800 secondsr AS INTERVAL )


‘ "8 00 00" // 0800/ 00 = 8 oras y 8/ =

select CAST( r0 minutesr AS INTERVAL )


ü

‘ "0 00 00" // rs min sec

The data types that contain a time value (TIME, TIME ITH TIME ZONE, TIMESTAMP, TIMESTAMP ITH
TIME ZONE, and INTERVAL) have microsecond precision. The DATE data type has a precision of one day.

_____________________________________

½  „    
 

PostgreSQL has a long history you can trace its history back to 1977 and a program known as Ingres. A lot has
changed in the relational database world since 1977.

÷‘ Schema

A schema is a named collection of tables. (see table). A schema can also contain views, indexes, sequences,
data types, operators, and functions. Other relational database products use the term catalog.

÷‘ „atabase

A database is a named collection of schemas. When a client application connects to a PostgreSQL server, it
specifies the name of the database that it wants to access. A client cannot interact with more than one
database per connection but it can open any number of connections in order to access multiple databases
simultaneously.

÷‘ ommand

A command is a string that you send to the server in hopes of having the server do something useful. Some
    !   . The two words are very similar in meaning and, in
practice,  
   " #

÷‘ Query

A query is a type of command that retrieves data from the server.

÷‘ Table (relation, file, class)


†

A table is a collection of rows. A table usually has a name, although some tables are temporary and exist
only to carry out a command. All the rows in a table have the same shape (in other words, every row in a
table contains the same set of columns). In other database systems, you may see the terms relation, file, or
even class these are all equivalent to a table.

÷‘ olumn (field, attribute)

A column is the smallest unit of storage in a relational database. A column represents one piece of
information about an object. Every column has a name and a data type. olumns are grouped into rows, and
rows are grouped into tables.

The terms field and attribute have similar meanings.

÷‘ ?ow (record, tuple)

A row is a collection of column values. Every row in a table has the same shape (in other words, every row
is composed of the same set of columns). If you are trying to model a real-world application, a row
represents a real-world object. For example, if you are running an auto dealership, you might have a
Ge icles table. Each row in the Ge icles table represents a car (or truck, or motorcycle, and so on).
The kinds of information that you store are the same for all Ge icles (that is, every car has a model
number, color, a vehicle I„, an engine, and so on).

You may also see the terms record or tuple these are equivalent to a row.

÷‘ omposite type

Starting with PostgreSQL version 8, you can create new data types that are composed of multiple values. For
example, you could create a composite type named address that holds a street address, city,
state/province, and postal code. When you create a table that contains a column of type address, you can
store all four components in a single field.

÷‘ „omain

A domain defines a named specialization of another data type. „omains are useful when you need to ensure
that a single data type is used in several tables. For example, you might define a domain named
accountNumber that contains a single letter followed by four digits. Then you can create columns of type
accountNumber in a general ledger accounts table, an accounts receivable customer table, and so on.

÷‘ ©iew

A view is an alternative way to present a table (or tables). You might think of a view as a "virtual" table. A
view is (usually) defined in terms of one or more tables. When you create a view, you are not storing more
data, you are instead creating a different way of looking at existing data. A view is a useful way to give a
name to a complex query that you may have to use repeatedly.

÷‘ lient/server


PostgreSQL is built around a client/server architecture. In a client/server product, there are at least two
programs involved. One is a client and the other is a server. These programs may exist on the same host or
on different hosts that are connected by some sort of network. The server offers a service; in the case of
PostgreSQL, the server offers to store, retrieve, and change data. The client asks a server to perform work; a
PostgreSQL client asks a PostgreSQL server to serve up relational data.

÷‘ lient

A client is an application that makes requests of the PostgreSQL server. Before a client application can talk
to a server, it must connect to a postmaster (see postmaster) and establish its identity. lient applications
provide a user interface and can be written in many languages.

÷‘ Server

The PostgreSQL server is a program that services commands coming from client applications. The
PostgreSQL server has no user interfaceyou can't talk to the server directly, you must use a client
application.

÷‘ Postmaster

Because PostgreSQL is a client/server database, something has to listen for connection requests coming
from a client application. That's what the postmaster does. When a connection request arrives, the
postmaster creates a new server process in the host operating system.

÷‘ Transaction

A transaction is a collection of database operations that are treated as a unit. PostgreSQL guarantees that all
the operations within a transaction complete or that none of them complete. This is an important propertyit
ensures that if something goes wrong in the middle of a transaction, changes made before the point of failure
will not be reflected in the database. A transaction usually starts with a BEGIN command and ends with a
COMMIT or ROLLBACK (see the next entries).

÷‘ ommit

A commit marks the successful end of a transaction. When you perform a commit, you are telling
PostgreSQL that you have completed a unit of operation and that all the changes that you made to the
database should become permanent.

÷‘ ?ollback

A rollback marks the unsuccessful end of a transaction. When you roll back a transaction, you are telling
PostgreSQL to discard any changes that you have made to the database (since the beginning of the
transaction).

÷‘ Index
Î

An index is a data structure that a database uses to reduce the amount of time it takes to perform certain
operations. An index can also be used to ensure that duplicate values don't appear where they aren't wanted.

÷‘ Tablespace

A tablespace defines an alternative storage location where you can create tables and indexes. When you
create a table (or index), you can specify the name of a tablespaceif you don't specify a tablespace,
PostgreSQL creates all objects in the same directory tree. You can use tablespaces to distribute the workload
across multiple disk drives.

÷‘ ?esult set

When you issue a query to a database, you get back a result set. The result set contains all the rows that
satisfy your query. A result set may be empty.

÷‘ olumn constraint

Is a condition that must be met by a column.

÷‘ Null ©alues

Sometimes when you add data to a table, you find that you don't know what value you should include for a
column. This value is unknown.

_________________________________________________________________________________

Y  
moGies database wit tapes, customers, and rentals

Because you are pretending to model a movie-rental business (that is, a video store), you will create tables that
model the data that you might need in a video store. Start by creating three tables: tapes, customers, and
rentals.

The tapes table is simple: For each videotape, you want to store the name of the movie, the duration, and a unique
identifier (remember that you may have more than one copy of any given movie, so the movie name is not sufficient
to uniquely identify a specific tape).

6ere is the command you should use to create the à  table:

CREATE TABLE tapes (


tape_id CHARACTER(8) UNIQUE, // column constraint UNIQUE, eac row in t e tapes
title CHARACTER VARYING(80), // table must aGe a unique tape_id
duration INTERVAL // an INTERVAL stores a period of time suc as  weeks, 
our  minutes, and so on
);
c!

The customers table is used to record information about each customer for the video store.

CREATE TABLE customers (


customer_id INTEGER UNIQUE,
customer_name VARCHAR(0),
p one CHAR(8),
birt _date DATE,
balance NUMERIC(
,)
);

?ents recorded in rentals

CREATE TABLE rentals (


tape_id CHARACTER(8),
customer_id INTEGER,
rental_date DATE
);

X    


„    

Notice that the each row in the rentals table refers to a row in the customer table (and a row in the tapes
table). In other words, there is a relationship between rentals and customers and a relationship between
rentals and tapes. The relationship between two rows is established by including an identifier from one row
within the other row. Each row in the rentals table refers to a customer by including the customer_id.
That's the heart of the relational database modelthe relationship between two entities is established by including the
unique identifier of one entity within the other.

 
 „ 


Use the interface pgAdminIII to do maintenance to database schema.

Ô
 × Y

M
î    

The two previous sections showed you how to create some simple tables and how to view the table definitions. Now
let's see how to insert data into these tables.

Ô
 × Y
The most common method to get data into a table is by using the INSERT command. Like most SQL commands,
there are a number of different formats for the INSERT command. Let's look at the simplest form first:
cc

" " #$


%&' (

 )’* +,

INSERT INTO customers VALUES(,rilliam Rubinr,r-r,r


0-- r,000);

6ere is an example that shows how to INSERT a customer who wasn't willing to give you his date of birth:

INSERT INTO customers(customer_name, p one, customer_id, balance) VALUES(


rilliam Rubinr,r-r, , 000);

This is equivalent to either of the following statements:

INSERT INTO customers(customer_name, birt _date, p one, customer_id, balance)


VALUES(rilliam Rubinr, NULL, r-r, , 000);

or

// use the order that the table has in table schema


INSERT INTO customers VALUES( , rilliam Rubinr, r-r, NULL, 000);

The final form for the INSERT statement allows you to insert one or more rows based on the results of a query:

INSERT INTO table ( column [, ) SELECT query;

Examples

)‘ INSERT INTO customer_backup SELECT * from customers;

)‘
INSERT INTO customers VALUES ( , rPanky, Henryr, r-r, r8-0-r,
000);
INSERT INTO customers VALUES (, rones, Henryr, r-r, r
0-0-0r,
000);
INSERT INTO customers VALUES (, ronderland, Alice Nr, r-r, r-
0 -0r, 00);
INSERT INTO customers VALUES (, rRubin, illiamr, r-r, r
-0
-0r,
00);

INSERT INTO tapes VALUES (rAB- r, rT e Godfat err);


INSERT INTO tapes VALUES (rAB-

r, rT e Godfat err);
INSERT INTO tapes VALUES (rMC-88
r, rCasablancar);
INSERT INTO tapes VALUES (rO-r, rCitizen Kaner);
INSERT INTO tapes VALUES (rAH-
0r, rRear indowr);

INSERT INTO rentals( 


 ’ 
 $
’- 
  + VALUES (rAB- r, r00--
r, );
INSERT INTO rentals( 
 ’ 
 $
’- 
  + VALUES (rAB-

r, r00--
r, );
INSERT INTO rentals( 
 ’ 
 $
’- 
  + VALUES (rO-r, r00--
r, );
INSERT INTO rentals( 
 ’ 
 $
’- 
  + VALUES (rMC-88
r, r00--
0r, );

=== SELECT customer_name, AGE( birt _date ) ROM customers;

SELECT * ROM tapes;


UPDATE tapes
set duration = r our  minutesr
HERE tape_id = rAH-
0r;

UPDATE tapes
set duration = r minutesr
HERE tape_id = rO-r;

UPDATE tapes
set duration = r our  minutesr
HERE tape_id = rMC-88
r;

UPDATE tapes
set duration = r our 0 minutesr
HERE tape_id = rAB-

r;

UPDATE tapes
set duration = r minutesr
HERE tape_id = rAB- r;

SELECT SUM(duration) ROM tapes;


SELECT SUM(duration) ROM tapes HERE title LIKE rT e Godfat err

SELECT title, SUM(duration) ROM tapes HERE title LIKE rT e Godfat err
GROUP BY title;

The inverse of COPY  TO is COPY  ROM. COPY  ROM imports data from an external file into a
PostgreSQL table. When you use COPY  ROM, the format of the text file is very important. The easiest way
to find the correct format is to export a few rows using COPY  TO, and then examine the text file.
If you decide to create your own text file for use with the COPY  ROM command, you'll have to worry about
a lot of details like proper quoting, column delimiters, and such. onsult the PostgreSQL reference documentation
for more details.

Anot er Example

create table customer(


customer_id integer,
customer_first_name Garc ar(00),
customer_last_name Garc ar(00));

create table lot(


lot_id integer,
lot_description Garc ar(00),
lot_size float,
lot_district integer,
lot_Galue float,
lot_street_address Garc ar(00));

create table customer_lot(


customer_id integer,
lot_id integer) ;

copy lot from rlotoutr


copy customer from rcustomeroutr
copy customer_lot from rcustomer_lotoutr
-------------------------------------------------

Y$ 


Other values that you might want to see are

select ; -- returns t e number  (w oopee)


select sqrt(0); -- returns t e square root of 
select timeofday();-- returns current date/time
select now(); -- returns time of start of transaction
select Gersion(); -- returns t e Gersion of PostgreSQL you are using

select now(), timeofday();

SELECT title ROM tapes;


SELECT customer_name, birt _date ROM customers;
SELECT customer_name, birt _date, age( birt _date ) ROM customers;

customer_name ´ birt _date ´ age


----------------------+------------+------------------------------

"Panky Henry"; "8-0-"; " years


mons  days"

"ones Henry"; "


0-0-0"; " 8 years  mons  days"
"onderland Alice"; "-0 -0"; "0 years  mons 0 days"
"Rubin illiam"; "
-0
-0"; "
years  mons  days"
( rows)

T e expression age(birt _date) is eGaluated for eac row in t e table T e


age() function subtracts t e giGen date from t e current date

| 
| 

!
The preceding few sections have shown you how to specify which columns you want to see in a result set. Now let's
see how to choose only the rows that you want.
First, I'll show you to how to eliminate duplicate rows; then I'll introduce the HERE clause.

SELECT [ALL ´ DISTINCT ´ DISTINCT ON ‘

SELECT title from tapes;

Notice that "The Godfather" is listed !


 (you own two copies of that video). You can use the „×Y× Y clause
to filter out duplicate rows:

SELECT DISTINCT title ROM tapes;

Now, try t is

SELECT DISTINCT title, tape_id ROM tapes;

We're back to seeing "The Godfather" twice. What happened? The DISTINCT clause removes duplicate rows, 

  %  ; and when the tape I„s are added to the result, the rows containing "The Godfather" are
no longer identical.
If you want to filter rows that have duplicate values in one (or more) columns, use the DISTINCT ON() form:

SELECT DISTINCT ON (title) title, tape_id ROM tapes;

SELECT DISTINCT ON (title,duration) * ROM tapes;

Notice that one of the "The Godfather" rows has been omitted from the result set. If you don't include an ORDER
BY clause (I'll cover that in a moment), you can't predict which row in a set of duplicates will be included in the
result set.

You can list multiple columns (or expressions) in the DISTINCT ON() clause.

‘‘HERE‘‘
The next form of the SELECT statement includes the X  clause. 6ere is the syntax diagram for this form:

SELECT expression-list ROM table HERE conditions

Using the W6E?E clause, you can filter out rows that you don't want included in the result set. Let's see a simple
example. First, here is the complete customers table:

SELECT * ROM customers;

Now pick out only those customers who owe you some money:

SELECT * ROM customers HERE balance > 0;

SELECT customer_name, p one, AGE(birt _date) ROM customers


HERE( balance = 0 ) AND ( extract(years from AGE(birt _date)) <= rr)
>> "Panky Henry";"-";" years
mons  days"
"ones Henry";"-";" 8 years  mons  days"

SELECT customer_name, p one, AGE(birt _date) ROM customers


HERE( balance = 0 ) OR ( extract(years from AGE(birt _date)) <= r
r);
>> "Panky Henry";"-";" years
mons  days"
"ones Henry";"-";" 8 years  mons  days"
"Rubin illiam";"-";"
years  mons SELECT customer_name, p one,
AGE(birt _date),balance ROM customers
HERE ( extract(years from AGE(birt _date)) =
);

 days"

SELECT * ROM customers


HERE NOT ( balance = 0 );

SELECT customer_id, customer_name ROM customers


HERE balance != 0;

Notice that a column of any data type can support NULL values.

The NULL value has a unique property that is often the source of much confusion. NULL is not equal to any value,
not even itself. NULL is not less than any value, and NULL is not greater than any value.

SELECT * ROM customers HERE balance > NULL;


customer_id ´ customer_name ´ p one ´ birt _date ´ balance


-------------+---------------+-------+------------+---------
(0 rows)

Let's add a customer with a NULL balance:

INSERT INTO customers VALUES (, r unkmaster, reddyr, r- UNKr,


null,null);

But remember, NULL is not equal to, greater than, or less than any other value. NULL is not the same as zero. ?ather
than using relational operators ( '=', '!=', '<', or '>'), you should use either the IS or IS NOT operator.

SELECT * ROM customers HERE balance IS NULL;

SELECT * ROM customers HERE balance IS NOT NULL;

SELECT customer_id, customer_name, balance, balance +  ROM customers;


>>
;"Panky Henry";000;00
;"ones Henry";000;00
;"onderland Alice"; 00;
00
;"Rubin illiam";00;00
;" unkmaster, reddy"; // null +  = null

This query shows what happens when you try to perform a mathematical operation using NULL. When you try to
add '' to NULL, you end up with NULL.

 ‘ !‘" ‘

PostgreSQL offers two operators that can convert a NULL value to some other value or convert a specific value into
NULL.

The COALESCE() operator will substitute a default value whenever it encounters a NULL.

Try the OALESE function:

Let's add a customer with a NULL phone:

× Y× Y  à àà  


 

SELECT customer_id, customer_name, COALESCE(p one, rNo se conocer ) ROM


customers;
>>

;"Panky Henry"; "-"


;"ones Henry"; "-"
;"onderland Alice"; "-"
;"Rubin illiam"; "-"
;" unkmaster, reddy"; "- UNK"
 !àà ! !"#!
-----------------------------------

SELECT customer_id, customer_name, COALESCE(balance, 0 ) ROM customers;


>>
;"Panky Henry"; 000
;"ones Henry"; 000
;"onderland Alice"; 00
;"Rubin illiam"; 00
 !$ " à$! 
;"Roxette Nurayama"; 00

--------------------------------

The NULLI () operator translates a non-NULL value into NULL. NULLI () is often used to do the opposite of
COALESCE(). COALESCE() T?ansforms NULL into a default valueNULLI () translates a default value into
NULL. In many circumstances, you want to treat a numeric value and a NULL value as being the same thing. For
example, the balance column (in the customers table) is NULL until a customer actually rents a tape: A NULL
balance implies that you haven't actually done any business with the customer yet. But a NULL balance also
implies that the customer owes you no money. To convert a NULL balance to 0, use COALESCE( balance,
0 ). To convert a zero balance to NULL, use NULLI ( balance, 0 ). When PostgreSQL evaluates an
NULLI ( arg, arg ) expression, it compares the two arguments; if they are equal, the expression evaluates
to NULL; if they are not equal, the expression evaluates to the value of arg1.

SELECT customer_id,balance, NULLI ( balance, 0 ) ROM customers


ORDER BY customer_id;

customer_id / balance / NULLI ( balance, 0 )


; 000; null
; 00; 00
; 000; null
; 00; 00
; null null
; 00; 00
--------------------------------------------

Y COALESCE‘ ‘NULLI ‘ ‘‘


 ‘
‘ ‘
‘‘
‘‘
‘‘ ‘‘ 

#à %& à à àà & à



c

& à  '



CREATE UNCTION isEmpty (c aracter Garying, c aracter Garying)
RETURNS c aracter Garying
AS $$
declare
fnRetTrue alias for $;
fnRet alse alias for $;
begin
if fnRetTrue = rr OR fnRetTrue is NOT NULL t en
return fnRetTrue;
else
return fnRet alse;
end if;
end;
$$
LANGUAGE plpgsql;

>> select isEmpty(null,rNulor)

CREATE UNCTION isNumericNull (real, c aracter Garying)


RETURNS c aracter Garying
AS $$
declare
fnRetTrue alias for $;
fnRet alse alias for $;
begin
if fnRetTrue = 0 OR fnRetTrue is NOT NULL t en
return fnRetTrue;
else
return fnRet alse;
end if;
end;
$$
LANGUAGE plpgsql;

>> select isNumericNull(null,rSin Valorr)

-----------------------------------------------------------------------

Truth Tables


 ‘ ‘
‘ 
#$!‘AND‘"
 
‘

 "  „"


trUE trUE trUE
trUE ALSE ALSE
trUE NULL NULL
ALSE ALSE ALSE
ALSE NULL ALSE
NULL NULL NULL
Source: PostgreSQL User's Guide

‘
 ‘ ‘
‘ 
#$!‘OR‘"
 
‘

 "  "
trUE trUE trUE
trUE ALSE TRUE
TRUE NULL trUE
ALSE ALSE ALSE
ALSE NULL NULL
NULL NULL NULL
Source: PostgreSQL User's Guide

‘
‘
‘
‘
‘
 ‘ ‘
‘NOT‘"
 
‘
 Y
å!

‘
‘
‘
‘
‘
 ‘ ‘
‘NOT‘"
 
‘

 Y
trUE ALSE
ALSE trUE
NULL NULL
Source: PostgreSQL User's Guide

  


The CASE expression is a more generic form of NULLI and COALESCE(). A CASE expression lets you map
any given value into some other value. You can write a CASE expression in two different forms. The first form
(called the simple form) looks like this:

CASE expression
HEN Galue THEN result
HEN Galue THEN result

[ ELSE resultn
END

When PostgreSQL evaluates a simple CASE expression, it computes the value of expression then compares the
result to Galue. If expression equals Galue, the CASE expression evaluates to result. If not,
PostgreSQL compares expression to Galue; if they match, the CASE expression evaluates to result.
PostgreSQL continues  
   X    


 . If none of the values match
  , the expression evaluates to the value specified in the ELSE clause. If PostgreSQL gets all the way
to the end of the list and you haven't specified an ELSE clause, the CASE expression evaluates to NULL. Note that
result, result, « resultn must all have the same data type.

You can see that NULLI ( balance, 0 ) is equivalent to

CASE balance
HEN 0 THEN NULL
ELSE balance
END
åc

$
.

CREATE TABLE test (


a INTEGER UNIQUE
);

insert into test Galues();


insert into test Galues();
insert into test Galues( );

SELECT * ROM test;

SELECT a, CASE HEN a= THEN roner


HEN a= THEN rtwor
ELSE rot err
END
ROM test;

;"one"
;"two"
;"ot er"

The second, more flexible form of the CASE expression is called the searched form:

CASE
HEN condition THEN result
HEN condition THEN result

[ ELSE resultn
END

When PostgreSQL evaluates a searched CASE expression, it first evaluates condition. If condition
evaluates to TRue, the value of the CASE expression is result. If condition evaluates to false,
PostgreSQL evaluates condition. If that condition evaluates to true, the value of the CASE expression is
result. Otherwise, PostgreSQL moves on to the next condition. PostgreSQL continues to evaluate each
condition until it finds one that evaluates to true. If none of the conditions is true, the CASE expression
evaluates to resultn. If PostgreSQL gets all the way to the end of the list and you haven't specified an ELSE
clause, the CASE expression evaluates to NULL.

Like the simple form, result, result, « resultn must all have the same data type. 6owever, in the
searched form, the conditions don't have to be similar to each other. For example, if you want to classify the titles in
your tapes collection (and you're a big Jimmy Stewart fan), you might use a CASE expression like this:
åå

SELECT customer_name, p one, birt _date,balance,


CASE
HEN balance > 0 THEN r ig debtr
HEN extract(years from AGE(birt _date)) > 0 THEN rmature peopler
HEN p one is null THEN rcustomer do not aGe p oner
END
ROM customers;

"Panky Henry"; "-"; "8-0-"; 000; "mature people"


"ones Henry"; "-"; "
0-0-0"; 000; null
"onderland Alice"; "-"; "-0 -0"; 00; null
"Rubin illiam"; "-"; "
-0
-0"; 00; " ig debt"
" unkmaster, reddy"; "- UNK"; null null null
"Roxette Nurayama"; null; "
-0-0"; 00; "customer do not aGe
p one"
-----------------------------------------------------------------------------
-------
( rows)

Y  „()  

So far, all the queries that you have seen return rows in an arbitrary order. You can add an ORDER BY clause to a
SELECT command if you need to impose a predictable ordering. The general form of the ORDER BY clause is

PostgreSQL supports another form for the ORDER BY clause: ORDER BY expression [ USING operator
[,  . This might seem a little confusing at first. When you specify ASC, PostgreSQL uses the < operator to
determine row ordering. When you specify DESC, PostgreSQL uses the > operator. The second form of the ORDER
BY clause allows you to specify an alternative operator.

ORDER BY expression [ ASC ´ DESC [, 

or null Galues, null is always considered larger than all other values when evaluating an ORDER BY
clause.

The ASC and DESC terms mean ascending and descending, respectively. If you don't specify ASC or DESC,
PostgreSQL assumes that you want to see results in ascending order. The expression following ORDER BY is
called a sort key.

Let's look at a simple example:

SELECT * ROM customers ORDER BY balance;

; "Panky Henry"; "-"; "8-0-"; 000


; "ones Henry"; "-"; "
0-0-0"; 000
; "onderland Alice"; "-"; "-0 -0"; 00
å‰

; "Rubin illiam"; "-"; "


-0
-0"; 00
; "Roxette Nurayama"; null "
-0-0"; 00
; " unkmaster, reddy"; "- UNK"; null null
---------------------------------------------------------

SELECT * ROM customers ORDER BY balance DESC;

You can include multiple sort keys in the ORDER BY clause. The following query sorts customers in ascending
balance order, and then in descending birt _date order:

SELECT * ROM customers ORDER BY balance, birt _date DESC;

c &' (  & &)))cc& &ccc& #


* &+ (  & &)))cc& &ccc& #
4; "Wonderland Alice"; "555-1122"; "1969-03-05"; 3.00

Occasionally, you will find that you want to answer a question such as "Who are my top 10 salespeople?" In most
relational databases, this is a difficult question to ask. PostgreSQL offers two extensions that make it easy to answer
"Top n" or "Bottom n"-type questions. The first extension is the ××Y clause. The following query shows the two
customers who owe you the most money:

SELECT * ROM customers ORDER BY balance DESC LIMIT ;

Let's change this query a little. This time we want the top five customers who have a balance over $10:

SELECT * ROM customers HERE balance >= 0
ORDER BY balance DESC LIMIT ;

;"Roxette Nurayama"; null; "


-0-0"; 00
;"Rubin illiam"; "-"; "
-0
-0"; 00

The second extension is the $$Y  . The O SET n clause tells PostgreSQL to skip the first n rows of
the result set. For example, the form would be

Y*$ Y+××Y +&# à%à à $$Y " 


  


Example
SELECT * ROM myTable LIMIT 00 O SET 0;
å 

× Y× Y  à ,  #  

SELECT customer_name, balance ROM customers ORDER BY balance DESC;

customer_name balance
" unkmaster, reddy"; null
"Paul Newman"; null
"Rubin illiam"; 00
"Roxette Nurayama"; 00
"onderland Alice"; 00
"Panky Henry"; 000
"ones Henry"; 000
------------------------------------

SELECT customer_name, balance ROM customers HERE balance IS NOT NULL ORDER
BY balance DESC;

O SET

SELECT customer_name, balance ROM customers ORDER BY balance DESC O SET ;

customer_name balance
"Paul Newman"; null
"Roxette Nurayama"; 00
"Rubin illiam"; 00
"onderland Alice"; 00
"Panky Henry"; 000
"ones Henry"; 000
------------------------------------

Observe the following QUE?Y: Get the two younger customers;

SELECT customer_name, birt _date,balance ROM customers


ORDER BY birt _date DESC LIMIT ;

There is a tie for dates and 'Paul Newman' does not come out in the report!!!

SELECT customer_name, birt _date,balance ROM customers


ORDER BY birt _date DESC LIMIT ;
å·

customer_name birt _date balance


" unkmaster, reddy"; null null
"Roxette Nurayama"; "
-0-0"; 00
"Paul Newman"; "
-0-0"; null // only if you use Limit
-----------------------------------------------

No way out, we must use SQL: query co-relational

6ere is the answer to the query:

SELECT customer_name, birt _date,balance ROM customers a


HERE  > (SELECT COUNT(*) ROM customers b HERE abirt _date <
bbirt _date )
ORDER BY birt _date DESC;

The next Query considers only the years from customers:

SELECT customer_name, extract(years from AGE(birt _date)) AS Years ROM


customers a
HERE  > ( SELECT COUNT(*) ROM customers b
HERE extract(years from AGE(abirt _date)) > extract(years from
AGE(bbirt _date)) )
ORDER BY birt _date DESC;

Customer_name Years
-----------------------------------
" unkmaster, reddy"; null
"Roxette Nurayama"; 
"Paul Newman"; 

Ë
   

SELECT customer_id, customer_name,balance AS "Old balance", balance +  AS


"New balance"
ROM customers
ORDER BY "New balance";

customer_id customer_name "Old balance" "New balance"

; "Panky Henry"; 000; 00


; "ones Henry"; 000; 00
; "onderland Alice" 00;
00
; "Rubin illiam"; 00; 00
; "Roxette Nurayama"; 00;  00
; " unkmaster, reddy null null

; "Paul Newman"; null null


åü

--------------------------------------------------------------------------------

M  

PostgreSQL offers a number of aggregate functions. An aggregate is a collection of thingsyou can think of an
aggregate as the set of rows returned by a query. An aggregate function is a function that operates on an aggregate

OUNT() returns the number of objects in an aggregate. The OUNT() function comes in four forms:

÷‘ COUNT(*)
÷‘ COUNT( expression )
÷‘ COUNT( ALL expression )
÷‘ COUNT( DISTINCT expression )

SELECT * ROM customers

SELECT COUNT(*) ROM customers; // COUNT(*) pays attention to t e HERE


clause In ot er
words, COUNT(*) returns t e number of rows
t at filter
t roug t e HERE clause
SELECT COUNT( balance ) ROM customers; // returns t e number of non-NULL
Galues in t e
aggregate
SELECT COUNT( p one ) ROM customers;

SELECT COUNT( * ) ROM customers; --


all t em
SELECT COUNT( balance ) ROM customers; -- not considered null Galues 
SELECT COUNT(*) - COUNT( balance ) ROM customers; -- returns t e number of
rows wit NULL SELECT COUNT(
DISTINCT balance ) ROM customers;

OUNT(), and in fact all the aggregate functions (except for OUNT(*)), ignore NULL values.

|Ô

The SUM( expression ) function returns the sum of all the values in the aggregate expression. You can also specify
an arbitrarily complex expression as long as that expression results in a numeric value. onsidering a very classic
case, we may add SUM((price*quantity)*1.15), then the query can be written as

SELET SUM( (price * quantity) * 1.15 ) F?OM Factura_„etalle


W6E?E folio_factura = variablefolio;
å†

With our database:

SELECT SUM( balance ) ROM customers;


SELECT SUM( balance * 0 ) ROM customers;

SELECT SUM( duration ) ROM tapes HERE ;

|$ $Y, ,--. % ,c /)


 ,--. %  

aqui

Let¶s update t e tapes table

UPDATE tapes
set duration = r our  minutesr
HERE tape_id = rAH-
0r;

UPDATE tapes
set duration = r minutesr
HERE tape_id = rO-r;

UPDATE tapes
set duration = r our  minutesr
HERE tape_id = rMC-88
r;

UPDATE tapes
set duration = r our 0 minutesr
HERE tape_id = rAB-

r;

UPDATE tapes
set duration = r minutesr
HERE tape_id = rAB- r;
SELECT SUM(duration) ROM tapes;
‘ Sum interGal
------------
"0
0 00"

‘ Sum interGal
------------
å

"0  00"

M 0

The A©G( expression ) function returns the average of an aggregate expression.

SELECT AVG( balance ) ROM customers


HERE balance IS NOT NULL;
SELECT SUM(duration) ROM tapes HERE title LIKE rT e Godfat err;

And the next query is equivalent

Y+-  Y+$  à

But these queries are not equivalent:

SELECT AVG( balance ) ROM customers;


SELECT SUM( balance ) / COUNT( * ) ROM customers;

Why not? Because COUNT( * ) counts all rows whereas COUNT( balance ) omits any rows where the
balance is NULL.

.M 

The MIN( expression ) and MAX( expression ) functions return the minimum and maximum values, respectively, of
an aggregate expression. The MIN() and MAX() functions can operate on numeric, date/time, or string aggregates:

SELECT MIN( balance ), MAX( balance ) ROM customers;

SELECT MIN( birt _date ), MAX( birt _date ) ROM customers;

Observe this query and compare

SELECT customer_name ROM customers


ORDER BY customer_name DESC;

With this
åÎ

SELECT MIN( customer_name ), MAX( customer_name )


ROM customers;

 M  Ë




In addition to OUNT(), SUM(), A©G(), MIN(), and MAX(), PostgreSQL also supports the ST„„E©(expression)
and ©A?IANE( expression ) aggregate functions. These last two aggregate functions compute the standard
deviation and variance of an aggregate, two common statistical measures of variation within a set of observations.

SELECT COUNT(balance),SUM(balance),AVG(balance), MIN(balance), MAX(balance),STDDEV(balance)


from customers;

COUNT(balance)/SUM(balance)/ AVG(balance)/ MIN(balance)/ MAX(balance)/ STDDEV(balance)


------------- ------------ ----------- ------------ ------------ --------------
 
00 00000000 000 00 0 800  8

0
  

The aggregate functions are useful for summarizing information. The result of an aggregate function is a single
value. Sometimes, you really want an aggregate function to apply to each of a number of subsets of your data. For
example, you may find it interesting to compute some demographic information about your customer base.

SELECT COUNT(*) as Cantidad, title as Título ROM tapes


GROUP BY title;

Cantidad Título
 "T e Godfat er"
 "Casablanca"
 "Rear indow"
 "T e Birds"
 "Citizen Kane"
--------------------------------

 SELECT customer_id,  COUNT(*) AS Rentas


 ROM rentals
 GROUP BY customer_id
ORDER BY customer_id;

customer_id Rentas
‰!

 

-------------------------

EXT?AT and „EA„E

A 
  is a sequence of characters, denoting the date and/or time at which a certain event occurred. This data
is usually presented in a consistent format, allowing for easy comparison of two different records and tracking
progress over time; the practice of recording timestamps in a consistent manner along with the actual data is called

 
.

Timestamps are typically used for logging events, in which case each event in a log is marked with a timestamp. In
filesystems, timestamp may mean the stored date/time of creation or modification of a file.

The extract function is primarily intended for computational processing.

CENTURY
SELECT EXTRACT(CENTURY ROM TIMESTAMP r00-0- 0 8 0r);

? 

DAY
SELECT EXTRACT(DAY ROM TIMESTAMP r00-0-  8 0r);

?  

DO
T e day of t e week (0 - ; Sunday is 0) (for timestamp Galues only)
SELECT EXTRACT(DO ROM TIMESTAMP r00-0-  8 0r);

? 


DAY
Day of t e year ( - / ) (for timestamp Galues only)
SELECT EXTRACT(DOY ROM TIMESTAMP r00-0-0  8 0r)

? 


EPOCH
Ô ‘‘
‘interGal‘ ‘ ‘
 ‘ ‘
‘
‘‘ ‘ ‘!‘
‰c

‘
SELECT EXTRACT(EPOCH ROM INTERVAL r minuter);
?  

SELECT EXTRACT(EPOCH ROM INTERVAL r ourr);
? 

SELECT EXTRACT(EPOCH ROM INTERVAL r daysr);
?   


?

SELECT * ROM tapes;

SELECT SUM(EXTRACT(EPOCH ROM duration))AS SECONDS ROM tapes;


Result 800

SELECT SUM(EXTRACT(EPOCH ROM duration)) / 0 AS MINUTES ROM tapes;


Result  0

SELECT EXTRACT(EPOCH ROM duration) / 0 AS MINUTES ROM tapes HERE tape_id


= rAH-
0r;
?  

SELECT (EXTRACT(EPOCH ROM duration) / 0 ) / 0 AS HOURS
ROM tapes HERE tape_id = rAH-
0r;
? 

SELECT EXTRACT(HOUR ROM duration) AS HOURS, EXTRACT(MINUTE ROM duration) AS
MINUTES
ROM tapes;
Result rs, min of all t em

SELECT EXTRACT(HOUR ROM duration) AS HOURS, EXTRACT(MINUTE ROM duration) AS
MINUTES
ROM tapes HERE tape_id = rAH-
0r;
?  !
‰å

SELECT SUM(EXTRACT(HOUR ROM duration)) AS HOURS, SUM(EXTRACT(MINUTE ROM


duration)) AS MINUTES
ROM tapes;
Result  ours, 0 minutes

SELECT SUM( (EXTRACT(HOUR ROM duration)) * 0) + SUM(EXTRACT(MINUTE ROM


duration)) AS MINUTES
ROM tapes;
Result  0 minutes

Hour
T e our field (0 -  ) 

SELECT EXTRACT(HOUR ROM TIMESTAMP r00-0-  8 0r);



? 

Minute
T e minutes field (0 - )

SELECT EXTRACT(MINUTE ROM TIMESTAMP r00-0-  8 0r);


Result 8


 ‘
"
‘  ‘ ‘ ‘ ‘
‘ ‘
 ‘ ‘ ‘# ‘$‘%‘$&‘'‘
‘ ‘
 ‘ ‘ ‘
‘
 ‘

‘$&‘(‘%‘$$‘‘
‘
SELECT EXTRACT(MONTH ROM TIMESTAMP r00-0-  8 0r);
? 

SELECT EXTRACT(MONTH ROM INTERVAL r years mont sr);


Result

 )*+‘
, ‘
‘ ‘-‘  
 ‘ ‘(‘%‘./‘‘
‘
SELECT EXTRACT(SECOND ROM TIMESTAMP r00-0-0  8 0r);
? 0

SELECT EXTRACT(SECOND ROM TIME r 8 0r);


‰‰

? 0
‘

0‘‘

"
‘ ‘timestamp‘ ‘  ‘ ‘ ‘
‘ ‘0‘
‘ ‘# ‘ ‘ ‘ #‘‘‘
1#‘ 
‘2)‘34($‘ ‘ ‘0‘
‘ ‘# ‘
 ‘5  #‘6‘
‘ ‘# ‘, ‘2)‘
0‘  ‘
‘ 
 #‘ 2‘
 ‘ 
‘  ‘ ‘ ,  #‘
‘ ‘ # ‘‘‘ 0‘ $‘
‘ ‘
# ‘‘

SELECT EXTRACT(EEK ROM TIMESTAMP r00-0-0  8 0r);


? 
‘

7 ‘‘
, ‘# ‘ ‘‘
SELECT EXTRACT(YEAR ROM TIMESTAMP r00-0-   0r);
?  


The  1function is the traditional Postgres equivalent to the SQL-function extract:

date_part(ru "r, #$ )

*
‘ ‘ ‘ ‘u "‘ ‘‘
‘‘ ‘-‘, ‘ ‘ ‘ ‘
‘date_part‘
‘ ‘ ‘ ‘
‘extract‘‘
‘
SELECT date_part(rdayr, TIMESTAMP r00-0-   0r);
? 

SELECT date_part(r ourr, INTERVAL r ours minutesr)


? 

 Y 

, ‘

-‘ 
‘ ‘   ‘
‘
 ‘ ‘‘ ‘ 8
‘ !‘‘

÷‘ CURRENT_TIME
÷‘ CURRENT_DATE
÷‘ CURRENT_TIMESTAMP
‰ 

*
‘ ‘ ‘
‘ ‘9 ‘
‘ ‘:;‘  ‘ ‘ 
‘ ‘
‘‘
 ‘ ‘ -‘  ‘‘

SELECT CURRENT_TIME;
"  8
-0" // Time wit time zone

SELECT CURRENT_DATE;
"00-0-"

SELECT CURRENT_TIMESTAMP;
"00-0-  8 
-0"

"00-0-   

-0"

, ‘ 
‘now()‘‘ ‘ 
 ‘<
-‘9 ‘
‘CURRENT_TIMESTAMP‘‘

, ‘‘ 
‘timeofday()‘  ‘‘‘ ‘
‘ - ‘
‘ ‘ ‘
CURRENT_TIMESTAMP‘ #‘
!‘‘

SELECT timeofday();
"ed Sep   0 8
000 00 CDT" //time of day, text

timeofday()‘‘ ‘
 -‘# ‘ ‘gettimeofday()‘  ‘ #‘ ‘


‘-

‘ ‘ 

‘-‘
‘#
‘ 
 '‘ ‘
 ‘ 
‘#‘
‘time()‘
  ‘‘‘
‘
%
‘

‘"
‘ 
 ‘ 
’à& 
   

   

2‘‘9‘ 
 ‘
‘ =‘ ‘CURRENT_TIMESTAMP‘ ‘ ‘ 
‘ ‘‘ ‘
 ‘ ‘
‘ ‘ ‘
‘ ‘‘  
'‘ ‘ ‘
‘
‘ ‘ ‘ ‘
  
‘‘-‘1‘timeofday()‘‘ ‘  ‘‘ ‘‘

‘ ‘ 8 ‘  ‘#‘ 


‘ ‘ ‘ ‘ ‘ ‘now‘
‘ #‘ ‘‘
 ‘ ‘ ‘, ‘ ‘

-‘ ‘ ‘‘ ‘ ‘!‘‘

-‘ SELECT TIMESTAMP rnowr; // "00-0-  8


"
-‘ SELECT now(); // "00-0-   8
8-0"
-‘ SELECT CURRENT_TIMESTAMP; // "00-0-   0
0-0"

î 7
‘
‘
‘ ‘
‘‘ ‘ ‘
 ‘ ‘ #-‘ ‘+" Ô;,‘ ‘ ‘
 -‘ ‘ ‘, ‘# ‘‘
‘now‘
‘ ‘  ‘ ‘

‘ ‘ ‘
 ‘‘
‰·

 ‘
‘ ‘ ‘ ‘ ‘ ‘‘‘ ‘ ‘
‘ ‘ ‘ 
‘
‘‘
>‘, ‘ ‘
‘
 ‘‘
‘‘  ‘‘ ‘ ‘ ‘‘‘ ‘ #‘
‘ 
‘ ‘, ‘ #‘‘-‘ ‘‘ 

‘ -‘
‘ ‘ ‘
‘


‘‘

(consider that U??ENT_„ATE = µ2009/09/16¶)

SELET U??ENT_„ATE - (U??ENT_„ATE - 1); // 1 day


SELET U??ENT_„ATE - '2009/09/10'; // 6 days
SELET ('2009-09-16'::„ate - '2008-09-10'::„ate); // 371 days

SELET AGE(U??ENT_„ATE, '2008-09-16'::„ate); // 1 year


SELET AGE(U??ENT_„ATE, '2008-09-16'); // 1 year

SELET AGE('2000-09-16'::„ate); // 9 years


SELET date_part('month','2009-09-16'::„ate); // 9
SELET date_part('month','2009-09-16'::„ate) - date_part('month','2009-01-01'::„ate); // 9 ± 1 = 8


× Y

SELECT (r00-0-8 00 00 00r Timestamp) - (r00-0-

00 00 00r Timestamp);

SELECT (r00-0-8 00 00 00r Timestamp) + INTERVAL r MONTH  DAYr;

SELECT (r00-0-8 00 00 00r Timestamp) + INTERVAL r MONTH  DAY  HOUR


0 MINUTESr;

SELECT (r00-0-8 0 0 00r Timestamp) - INTERVAL r  MINUTESr;

SELECT INTERVAL r MINUTESr * ;

SELECT INTERVAL r0 MINUTESr / ;

SELECT INTERVAL r MONTHr - INTERVAL r MONTHr;

SELECT INTERVAL r MONTH  DAYr - INTERVAL r MONTHr; //  mons  days"

SELECT INTERVAL r MONTH  DAYr - INTERVAL r MONTH  DAYr; // " mons"

SELECT INTERVAL r MONTH  DAYr - INTERVAL r MONTH  DAYr; // " mons - 


days"

SELECT INTERVAL r MONTH  DAYr - INTERVAL r DAYr;// " mons -  days"
‰ü

-------------------------------------------------------------------------------------------------------------------------------------------

   



           
 


Y   Y   ‘

î
     
 
Y

? ‘  ‘ ‘‘ '‘ ‘‘ ‘‘


‘ 
‘
‘‘

? ‘  ‘ ‘‘ ‘ ‘‘ ‘‘

‘ #'‘‘ 
‘

‘‘

?  ‘  ‘‘‘ ‘ ‘‘ ‘‘


‘ '‘‘ 
‘

‘‘

 ? ‘ 
‘  ‘ ‘ 
‘  ? @
@‘ &(‘
  ‘ 
‘  8 ‘ ‘   ‘@&(($%
9 ‘
‘ (&%$4‘&(!A3!6(@‘
extract'‘‘ 
‘

‘‘

 ? ‘ 
‘  ‘ ‘ 
‘  ? @
 @‘ A‘
 ‘ 
‘  ‘ ‘  ‘@&‘# ‘A‘
9 ‘
‘
 @‘
extract'‘‘ 
‘

‘‘

 ?‘   ‘ ‘ ‘


‘  ?@
@‘ &(($%(&%$4‘
  ‘  ‘
'‘   ‘@&(($% &(!((!((B((‘
‘ 
‘
‘‘ (&%$4‘&(!A3!6(@‘
‰†

î
     
 
Y

  ‘ 


‘  ‘ ‘ 
‘  
‘ 
‘ &(‘

‘  ‘ 
‘  8 ‘ '‘‘   ‘@&(($%

‘
‘‘ (&%$4‘&(!A3!6(@‘

  ‘ 


‘  ‘ ‘ 
‘  
 ‘ A‘

‘ ‘ 
‘  ‘ '‘‘ 
‘ ‘@&‘

‘
‘‘ # ‘A‘
 @‘

   ‘ 

 ‘ C‘‘ ‘ ‘    ‘ ‘


 ‘ ‘‘ ‘ @&(($%(&%$4‘
 ‘ ‘
‘ &$!&3!A(@‘
 #‘

  ‘ 

 ‘ C‘‘ ‘ ‘   ‘@6‘ ‘


 ‘‘ ‘‘
@‘
- ‘


‘   ‘‘‘ ‘ ‘‘ ‘‘
‘ ‘9 ‘

‘
current_timestamp'‘
‘ 
‘
‘‘

 
 #‘ ‘ ‘ - %
‘  
 #‘ ‘"‘&$‘
 ‘ ‘ '‘‘ $D!($!$A((($&4‘

‘
‘‘ &(($‘,‘

   ‘   ‘


‘ ‘
‘    ‘ &(((%$&%&.‘
  ‘ @&(((%$&%&.@‘ ((!((!((‘

   ‘   ‘


‘ ‘ ‘    ‘ $//3%(&%&6‘
 ‘  ‘
‘ ‘  ‘ @$//3%(&%&6@ ‘ &A!(D!((‘
@&A!(D@‘
‰

Some examples:

SELECT to_c ar(birt _date, rYYYY-MM-DDr) ROM customers;

To_char text
"8-0-"
"
0-0-0"
"-0 -0"
"
-0
-0"
null
"
-0-0"
"
-0-0"
--------------------

You are doing a migration from MySQL to Postgres You aGe a field of type
"timestamp wit out time zone" and you need get only t e date part

SELECT to_c ar(TIMESTAMP r00-0-  8 0r, rYYYY-MM-DDr); // formatting


it
? ‘"00-0-"

select extract(hour from TIMESTAMP '2009-09-16 11:38:40');


select extract(minute from TIMESTAMP '2009-09-16 11:38:40');
select extract(second from TIMESTAMP '2009-09-16 11:38:40');

--------------------------------------------------------------------------------------------

©I„EO ENT?O

CREATE TABLE tapes (


tape_id CHARACTER(8) UNIQUE,
title CHARACTER VARYING(80),
duration INTERVAL
);

CREATE TABLE customers (


customer_id INTEGER UNIQUE,
customer_name VARCHAR(0),
p one CHAR(8),
birt _date DATE,
balance NUMERIC(
,)
‰Î

);

CREATE TABLE rentals (


tape_id CHARACTER(8),
customer_id INTEGER,
rental_date DATE
);

UPDATE tapes
SET duration = r0  00r
HERE tape_id = rAB- r;

SELECT * ROM tapes;


>>
"AB-

";"T e Godfat er";""
"MC-88
";"Casablanca";""
"O-";"Citizen Kane";""
"AH-
0";"Rear indow";""
"AB- ";"T e Godfat er";"0  00"

UPDATE tapes
SET duration = r0  00r
HERE tape_id = rAB-

r;

UPDATE tapes
SET duration = r0  00r
HERE tape_id = rMC-88
r;

UPDATE tapes
SET duration = r0  00r
HERE tape_id = rO-r;

SELECT * from tapes;

tape_id ´ title ´ duration


----------+---------------+--------------

"AB- "; "T e Godfat er"; "0  00"


"AB-

"; "T e Godfat er"; "0  00"
"MC-88
"; "Casablanca"; "0  00"
"O-"; "Citizen Kane"; "0  00"
"AH-
0"; "Rear indow";

ALTER TABLE tapes


ADD COLUMN male_lead VARCHAR(0),
 !

ADD COLUMN female_lead VARCHAR(0);

select * from tapes;

tape_id ´ title ´ male_lead ´ female_lead ´ duration


----------+----------------+-----------------+----------------+----------

"AB- "; "T e Godfat er"; "0  00"


"AB-

"; "T e Godfat er"; "0  00"
"MC-88
"; "Casablanca"; "0  00"
"O-"; "Citizen Kane"; "0  00"
"AH-
0"; "Rear indow";

UPDATE tapes
set male_lead = rMarlon Brandor
HERE title LIKE rT e Godfat err;

UPDATE tapes
set male_lead = rHump rey Bogartr, female_lead = rIngrid Bergmanr
HERE title LIKE rCasablancar;
UPDATE tapes
set male_lead = rames Stewartr, female_lead = rGrace Kellyr
HERE title LIKE rRear indowr;

SELECT * ROM tapes;

tape_id ´ title ´ male_lead ´ female_lead ´ duration


----------+-----------------+-------------------+----------------+----------

"O-"; "Citizen Kane"; "0  00"


"AB- "; "T e Godfat er"; "Marlon Brando"; "0  00"
"AB-

"; "T e Godfat er"; "Marlon Brando"; "0  00"
"AH-
0"; "Rear indow"; "ames Stewart"; "Grace Kelly"
"MC-88
"; "Casablanca"; "Hump rey Bogart";"Ingrid Bergman""0  00"

INSERT INTO tapes(tape_id,title,male_lead,female_lead,duration) VALUES(rAH-


8r,rT e Birdsr,null,rTippi Hedrenr,r0  00r);

SELECT tape_id,title,male_lead,female_lead,duration ROM tapes;

tape_id ´ title ´ male_lead ´ female_lead ´ duration


 c

----------+-----------------+-------------------+-----------------+----------
--

"O-"; "Citizen Kane"; "0  00"


"AB- "; "T e Godfat er"; "Marlon Brando"; "0  00"
"AB-

"; "T e Godfat er"; "Marlon Brando"; "0  00"
"AH-
0"; "Rear indow"; "ames Stewart"; "Grace Kelly"
"MC-88
"; "Casablanca"; "Hump rey Bogart"; "Ingrid Bergman";"0  00"
"AH-8"; "T e Birds"; "Tippi Hedren"; "0  00"

SELECT title, male_lead, duration,


CASE
HEN duration < r our  minr THEN rs ort moGier
HEN male_lead = rames Stewartr THEN rgreat moGier
HEN duration > r oursr THEN rlong moGier
END
ROM tapes;

title ´ male_lead ´ duration ´ case


---------------+-----------------+----------+-------------
T e Godfat er ´ Marlon Brando ´ 0  00 ´ long moGie
T e Godfat er ´ Marlon Brando ´ 0  00 ´ long moGie
Casablanca ´ Hump rey Bogart ´ 0  00 ´ s ort moGie
Citizen Kane ´ ´ 0  00 ´
Rear indow ´ ames Stewart ´ ´ great moGie
T e Birds ´ ´ 0  00 ´
( rows)
----------------

You can use the COALESCE() operator to transform a NULL male_lead into the word rUnknownr:

SELECT title, COALESCE( male_lead, rUnknownr ) ROM tapes;

SELECT title, COALESCE( male_lead, female_lead, rUnknownr ) AS "Starring"


ROM tapes;

title ´ Starring
---------------+-----------------
T e Godfat er ´ Marlon Brando
T e Godfat er ´ Marlon Brando
Casablanca ´ Hump rey Bogart
Citizen Kane ´ Unknown
Rear indow ´ ames Stewart
T e Birds ´ Tippi Hedren
( rows)
 å

The COALESCE() operator is more talented than we've shown hereit can search through a list of values, returning
the first non-NULL value it finds. For example, the following query prints the male_lead, or, if male_lead is
NULL, the female_lead, or if both are NULL, rUnknownr:

SELECT title, COALESCE( male_lead, female_lead, rUnknownr ) AS "Starring"


ROM tapes;

title ´ Starring
---------------+-----------------
T e Godfat er ´ Marlon Brando
T e Godfat er ´ Marlon Brando
Casablanca ´ Hump rey Bogart
Citizen Kane ´ Unknown
Rear indow ´ ames Stewart
T e Birds ´ Tippi Hedren
( rows)

You can string together any number of expressions inside of the COALESCE() operator (as long as all expressions
evaluate to the same type) and COALESCE() will evaluate to the leftmost non-NULL value in the list. If all of the
expressions inside COALESCE() are NULL, the entire expression evaluates to NULL.

X
% ‘& ‘ ‘$‘

PostgreSQL supports six basic date, time, and date/time data types, as shown in next table. I'll use the term temporal
to cover date, time, and date/time data types.

‘'
(‘ 
‘ ‘ ‘
„Y    Y  „|  $
„ 2Y
   „ 2Y
 
TIMESTAMP „ate/Time 4713 B 1465001 A„
TIMESTAMP ITH „ate/Time 1903 A„ 2037 A„

TIME ZONE
INTERVAL Interval -178000000 years 178000000 years
DATE „ate 4713 B 32767 A„
TIME Time 00:00:00.00 23:59:59.99
 ‰

‘'
(‘ 
‘ ‘ ‘
„Y    Y  „|  $
„ 2Y
   „ 2Y
 
TIME ITH Time 00:00:00.00+12 23:59:59.99-12

TIME ZONE
-------------------------------------------------------------------------------------------------------------------

„YM $

Some columns should not allow NULL values. In most cases, it would not make sense to add a customer to your
customers table unless you know the customer's name. Therefore, the customer_name column should be
mandatory (in other words, customer_name should not allow NULL values).

Let's drop and re-create the customers table so that you can tell PostgreSQL which columns should allow NULL
values:

DROP TABLE customers;


Ô usually means that you don't know what value should be entered into a column, but it can also mean that a
column does not apply. In reate table you can add this constraint.

YY( à 


 à.× Y  ×
 Y 
 à.  Y 
  / 
+à .à„Y 
+„×0 
 




Base de „atos ³?entals´


CREATE TABLE tapes (
tape_id CHARACTER(8) PRIMARY KEY,
title CHARACTER VARYING(80),
duration INTERVAL
);

CREATE TABLE customers (


customer_id INTEGER PRIMARY KEY,
customer_name VARCHAR(0),
  

p one CHAR(8),
birt _date DATE,
balance NUMERIC(
,)
);

CREATE TABLE rentals (


tape_id CHARACTER(8),
customer_id INTEGER,
rental_date DATE
);

INSERT INTO customers VALUES ( , rPanky, Henryr, r-r, r8-0-r,


000);
INSERT INTO customers VALUES (, rones, Henryr, r-r, r
0-0-0r,
000);
INSERT INTO customers VALUES (, ronderland, Alice Nr, r-r, r-
0 -0r, 00);
INSERT INTO customers VALUES (, rRubin, illiamr, r-r, r
-0
-0r,
00);
INSERT INTO customers VALUES (, r unkmaster, reddyr, r- UNKr,
null,null);
INSERT INTO customers VALUES (, rRoxette Nurayamar, null, r
-0-0r,
00);
INSERT INTO customers VALUES(
,rPaul Newmanr,r-r,r
-0-0r,null);

INSERT INTO tapes VALUES (rAB- r, rT e Godfat err);


INSERT INTO tapes VALUES (rAB-

r, rT e Godfat err);
INSERT INTO tapes VALUES (rMC-88
r, rCasablancar);
INSERT INTO tapes VALUES (rO-r, rCitizen Kaner);
INSERT INTO tapes VALUES (rAH-
0r, rRear indowr);

INSERT INTO rentals( 


 ’ 
 $
’- 
  + VALUES (rAB- r, r00--
r, );
INSERT INTO rentals( 
 ’ 
 $
’- 
  + VALUES (rAB-

r, r00--
r, );
INSERT INTO rentals( 
 ’ 
 $
’- 
  + VALUES (rO-r, r00--
r, );
INSERT INTO rentals( 
 ’ 
 $
’- 
  + VALUES (rMC-88
r, r00--
0r, );

UPDATE tapes set duration = r our  minutesr HERE tape_id = rAH-


0r;
UPDATE tapes set duration = r minutesr HERE tape_id = rO-r;
UPDATE tapes set duration = r our  minutesr HERE tape_id = rMC-88
r;
UPDATE tapes set duration = r our 0 minutesr HERE tape_id = rAB-

r;
UPDATE tapes set duration = r minutesr HERE tape_id = rAB- r;
 ·

ALTER TABLE tapes


ADD COLUMN male_lead VARCHAR(0),
ADD COLUMN female_lead VARCHAR(0);

UPDATE tapes
set male_lead = rMarlon Brandor
HERE title LIKE rT e Godfat err;

UPDATE tapes
set male_lead = rHump rey Bogartr, female_lead = rIngrid Bergmanr
HERE title LIKE rCasablancar;
UPDATE tapes
set male_lead = rames Stewartr, female_lead = rGrace Kellyr
HERE title LIKE rRear indowr;

INSERT INTO tapes(tape_id,title,male_lead,female_lead,duration) VALUES(rAH-


8r,rT e Birdsr,null,rTippi Hedrenr,r0  00r);

ALTE? TABLE customers


„?OP customers_customer_id_key;

?esult: E??O?: column "customers_customer_id_key" of relation "customers" does not exist

ALTE? TABLE customers


„?OP ONST?AINT customers_customer_id_key;

?esult: Query returned successfully with no result in 12 ms.

ALTE? TABLE customers


„?OP ONST?AINT customers_customer_id_key1;

?epitiendo el comando obtenemos:


E??O?: constraint "customers_customer_id_key1" does not exist

ALTE? TABLE customers


A„„ ONST?AINT customers_customer_id_key1 P?IMA?Y KEY(customer_id);

?EATE ©IEW ustomerTienen?entas AS


SELET customer_name AS Nombre, balance AS Saldo F?OM customers NATU?AL JOIN rentals;

?EATE ©IEW ustomerTienen?entas2 AS


 ü

SELET customer_id,customer_name AS Nombre, balance AS Saldo F?OM customers NATU?AL JOIN


rentals;

?EATE ©IEW ustomerTienen?entas3 AS


SELET customer_id,customer_name AS Nombre, phone F?OM customers
W6E?E customer_id IN ( SELET customer_id F?OM rentals );

UP„ATE ustomerTienen?entas3
SET phone = '888 7777'
W6E?E customer_id = 1;

E??O?: cannot update a view


6INT: You need an unconditional ON UP„ATE „O INSTEA„ rule.

SELET * F?OM ustomerTienen?entas3;

http://wiki.postgresql.org/wiki/?eturn_more_than_one_row_of_data_from_PL/pgSQL_functions

S-ar putea să vă placă și