Está en la página 1de 58

ESTE LIBRO ES UN PROYECTO DE TRADUCCIÓN DEL MANUAL DE POSTGRESQL 13 QUE

PUEDES ENCONTRAR EN POSTGRESQL.ORG


www.todopostgresql.com
ESTE LIBRO ES UN PROYECTO DE TRADUCCIÓN DEL MANUAL DE POSTGRESQL 13 QUE PUEDES ENCONTRAR EN POSTGRESQL.ORG

Este libro es un proyecto de traducción del Manual de PostgreSQL por


la empresa Abatic Soluciones Tecnológicas y que puedes encontrar en
postgresql.org

Traducción realizada por Javier Yugsi.

Diseño y maquetación por Jesús Fernández.

Más información en todopostgresql.com

2
www.todopostgresql.com
ESTE LIBRO ES UN PROYECTO DE TRADUCCIÓN DEL MANUAL DE POSTGRESQL 13 QUE PUEDES ENCONTRAR EN POSTGRESQL.ORG

ÍNDICE

Prólogo .................................................................................. 6

I · Preparación fundamental ............................................... 7

II · El lenguaje SQL ............................................................... 17

III · Características avanzadas ........................................... 39

3
ESTE LIBRO ES UN PROYECTO DE TRADUCCIÓN DEL MANUAL DE POSTGRESQL 13 QUE PUEDES ENCONTRAR EN POSTGRESQL.ORG
www.todopostgresql.com

4
ESTE LIBRO ES UN PROYECTO DE TRADUCCIÓN DEL MANUAL DE POSTGRESQL 13 QUE PUEDES ENCONTRAR EN POSTGRESQL.ORG
www.todopostgresql.com

PARTE 1: TUTORIAL

5
www.todopostgresql.com
ESTE LIBRO ES UN PROYECTO DE TRADUCCIÓN DEL MANUAL DE POSTGRESQL 13 QUE PUEDES ENCONTRAR EN POSTGRESQL.ORG

Prólogo

Bienvenido al tutorial de PostgreSQL. Los siguientes


capítulos han sido creados para dar una introducción
sencilla a lo que es PostgreSQL, a los conceptos de bases
de datos relacionales, y al lenguaje SQL. Este tutorial ha
sido desarrollado para cualquier persona que escucha por
primera vez estos conceptos, asumimos únicamente cierto
conocimiento general sobre el uso del ordenador. No es
necesario saber programar o saber utilizar sistemas Unix.
Esta parte pretende dar cierta experiencia práctica en
ciertos aspectos fundamentales del sistema de PostgreSQL,
no pretende ser una formación exhaustiva.

Tras finalizar este tutorial, quizá quieras continuar a la Parte


II, en donde ganarás mucha más experiencia trabajando con
el lenguaje SQL, o bien a la Parte IV, en donde aprenderás
más sobre cómo desarrollar aplicaciones para PostgreSQL.

La Parte III ha sido desarrollada específicamente para


DBAs, los temas de instalación y administración los podrás
encontrar aquí.

6
www.todopostgresql.com
ESTE LIBRO ES UN PROYECTO DE TRADUCCIÓN DEL MANUAL DE POSTGRESQL 13 QUE PUEDES ENCONTRAR EN POSTGRESQL.ORG

Preparación fundamental

1.1 Instalación:

Antes de que puedas utilizar PostgreSQL necesitarás


instalarlo. Es posible que PostgreSQL ya haya sido instalado
en tu puesto de trabajo, ya sea porque fue incluido en la
distribución de tu Sistema Operativo, o bien porque el
Administrador de Sistemas lo haya instalado. Si este es el
caso, deberás obtener información de la documentación de
tu sistema operativo, o bien contactar con tu Administrador
de Sistemas sobre cómo acceder a PostgreSQL.

Si no estas seguro de que tienes PostgreSQL, o de si puedes


utilizarlo de forma experimental, puedes instalarlo por ti
mismo. La instalación no es complicada y es un buen ejercicio.
PostgreSQL puede ser instalado por cualquier usuario, no
requiere accesos de administrador (root).

Si estás instalando PostgreSQL por ti mismo, dirígete al


Capítulo 16, en donde encontrarás instrucciones sobre la
instalación. Cuando termines la instalación, puedes volver
a este capítulo. Asegurate de seguir paso a paso la parte
en la que se explica el establecimiento de las variables del
sistema.

Si el administrador de sistemas no ha realizado una


instalación estándar en la que se han respetado los valores
por defecto, quizá tengas cierto trabajo adicional. Por

7
www.todopostgresql.com

ejemplo, si la máquina del servidor de Base de Datos es


una máquina en remoto, necesitarás ajustar la variable de
ESTE LIBRO ES UN PROYECTO DE TRADUCCIÓN DEL MANUAL DE POSTGRESQL 13 QUE PUEDES ENCONTRAR EN POSTGRESQL.ORG

entorno PGHOST al nombre de la máquina del servidor de


la Base de Datos. La variable de entorno PGPORT quizá
tenga que ser ajustada también. En conclusión, si intentas
ejecutar una aplicación, y esta lanza un error de conexión a
la Base de Datos, deberías consultar con tu administrador de
sistemas, o si tú eres el administrador de sistemas, entonces
dirigirte a la documentación para asegurarte de que tu
entorno ha sido instalado y ajustado adecuadamente. Si no
has entendido el último párrafo, entonces lee la siguiente
sección.

1.2 Fundamentos de la Arquitectura PostgreSQL

Antes de seguir es necesario que entiendas los conceptos


básicos de la Arquitectura de PostgreSQL. Entender cómo
las interactúan los diferentes componentes de PostgreSQL
será de gran ayuda.

En el vocabulario habitual de las Bases de Datos, PostgreSQL


utiliza un modelo cliente/servidor. Una sesión PostgreSQL
consiste en los siguientes procesos actuando en conjunto:

- Un proceso servidor que administra los archivos de


la base de datos, acepta conexiones a la base de datos de
diferentes aplicaciones y realiza acciones en la base de datos
en nombre de los clientes. El programa del servidor de la
base de datos se llama postgres.

- La aplicación del usuario cliente que quiere realizar


operaciones en la base de datos. Las aplicaciones cliente
pueden ser de diferente naturaleza: un cliente podría ser
una herramienta de texto, una aplicación gráfica, un servidor
8
www.todopostgresql.com

web que accede a la Base de Datos para mostrar páginas


web, o una aplicación especializada en el mantenimiento
ESTE LIBRO ES UN PROYECTO DE TRADUCCIÓN DEL MANUAL DE POSTGRESQL 13 QUE PUEDES ENCONTRAR EN POSTGRESQL.ORG

de la base de datos. Algunas de las aplicaciones cliente


son proveídas junto con la distribución de PostgreSQL, la
mayoría son desarrolladas por los usuarios.

- Tal y como es habitual en una aplicación cliente/


servidor, el cliente y el servidor pueden estar albergados en
diferentes sitios. En ese caso se comunican a través de una
conexión TCP/IP. Es importante recordar esto puesto que los
archivos que pueden accesibles en la máquina del cliente
pueden no ser accesibles desde la máquina del servidor.
El servidor de PostgreSQL puede administrar múltiples
conexiones simultáneas de clientes. Para hacerlo, inicia un
nuevo proceso por cada conexión. Desde ese momento, el
cliente y el nuevo proceso iniciado en el servidor, se comunican
sin intervención del proceso original postgres. Así pues, el
proceso maestro está siempre en ejecución, esperando
por conexiones con clientes, mientras los procesos cliente/
servidor vienen y van. Todo esto es invisible al usuario, se
menciona por la importancia en conocer lo que ocurre por
detrás.

1.3 Creando una Base de Datos.

Lo primero que puedes hacer para comprobar que tienes


acceso al servidor es intentar crear una base de datos. Un
servidor ejecutando PostgreSQL puede administrar varias
bases de datos. Normalmente, una base de datos diferente
es utilizada para cada proyecto o bien por cada usuario.

Puede ser que el administrador de sistemas ya haya creado


una base de datos para ti, en ese caso puedes omitir este
paso e ir al siguiente.
9
www.todopostgresql.com

Para crear una nueva base de datos, en este caso llamada


mydb, debes usar el siguiente comando:
ESTE LIBRO ES UN PROYECTO DE TRADUCCIÓN DEL MANUAL DE POSTGRESQL 13 QUE PUEDES ENCONTRAR EN POSTGRESQL.ORG

$ create mydb

Si este comando no genera una respuesta, entonces se ha


ejecutado de forma adecuada y puedes continuar sin leer lo
que queda de esta sección.

Por otro lado, si ves un mensaje similar al siguiente:

createdb: command not found

Entonces PostgreSQL no ha sido instalado de forma


adecuada. Puede ser que no haya sido instalado, o bien que
el directorio de PostgreSQL no ha sido instalado en el PATH
del sistema. Intentalo utilizando la ruta absoluta:

$ /usr/local/pgsql/bin/createdb mydb

La ruta en tu ordenador puede ser diferente. Compruébalo


con tu administrador o bien revisa las instrucciones de
instalación para corregir la situación.

Otra de las posibles respuestas puede ser:

10
www.todopostgresql.com

createdb: could not connect to database postgres: could not


connect to server: No such file or directory. Is the server
ESTE LIBRO ES UN PROYECTO DE TRADUCCIÓN DEL MANUAL DE POSTGRESQL 13 QUE PUEDES ENCONTRAR EN POSTGRESQL.ORG

running locally and accepting connections on Unix domain


socket “/tmp/.s.PGSQL.5432”?

Esto significa que el servidor no ha sido arrancado, o bien


que no ha sido arrancado donde createdb lo esperaba. Una
vez más debes consultar al administrador de sistemas p bien
revisar la instalación.

Otra de las posibles respuestas puede ser:

createdb: could not connect to database postgres: FATAL:


role “joe” does not exist.

en donde “joe” es tu propio nombre de usuario. Esto ocurrirá


si el administrador no ha creado un usuario para ti. (Las
cuentas de PostgreSQL son distintas para cada cuenta del
sistema operativo). Si tu eres el admnistrador, revisa el
capítulo 21 en donde encontrarás ayuda a la hora de crear
cuentas.
Necesitarás utilizar el usuario que instaló PostgreSQL,
habitualmente postgres, para crear la primera cuenta de
usuario. También puede haber ocurrido que se te asignó un
usuario PostgreSQL diferente al de tu sistema operativo, en
ese caso necesitarás usar la parámetro -U, o bien establecer
el mismo en la variable del sistema PGUSER

Si tienes una cuenta, pero esta no tiene los privilegios


requeridos para crear una base de datos, verás el siguiente
mensaje:

11
www.todopostgresql.com

createdb: database creation failed: ERROR: permission


denied to create database.
ESTE LIBRO ES UN PROYECTO DE TRADUCCIÓN DEL MANUAL DE POSTGRESQL 13 QUE PUEDES ENCONTRAR EN POSTGRESQL.ORG

No todos los usuarios tienen la autorización para crear


nuevas bases de datos. Si PostgreSQL rechaza la creación de
una Base de Datos, entonces el administrador debe darte
los permisos necesarios para la creación de Bases de Datos.
Consulta a tu administrador si esto ocurre. Si tú instalaste
PostgreSQL, entonces, para los propósitos de este tutorial,
deberías autenticarte en la cuenta que arrancó el servidor.

También puedes crear Bases de Datos con otros nombres.


PostgreSQL te permite crear cualquier número de Bases de
Datos en un mismo servidor. Los nombres de las bases de
datos deben empezar con un carácter alfabético, y están
limitados a 63 bytes de largo. Una opción recomendable es
crear la base de datos utilizando el mismo nombre de usuario.

Varias herramientas dan por hecho que el nombre por


defecto, por lo que hacerlo así te puede ahorrar algo de
tiempo. Para crear una base de datos que tiene el mismo
nombre que el usuario logado simplemente ejecutamos el
siguiente comando:

$ createdb

Si no quieres utilizar más tu base de datos, puedes borrarla.


Si eres el propietario(creador) de la base de datos mydb,
puedes borrarla utilizando el siguiente comando:

$ dropdb mydb

12
www.todopostgresql.com

(En este comando es obligatorio utilizar un nombre de base


de datos). Esta acción borra físicamente todos los archivos
ESTE LIBRO ES UN PROYECTO DE TRADUCCIÓN DEL MANUAL DE POSTGRESQL 13 QUE PUEDES ENCONTRAR EN POSTGRESQL.ORG

asociados con la base de datos y no puede deshecho, por lo


que debe ser hecho de forma muy meditada.

1.4 Accediendo a la Base de Datos.

Una vez creada la base de datos, puedes acceder a ella


mediante:

- Ejecutando el programa de terminal interactivo de


PostgreSQL llamado psql, este te permite entrar, editar y
ejecutar comandos SQL.

- Usando una terminal gráfica como pgAdmin o


una suite de oficina con soporte ODBC o JDBC para crear
y manipular la base de datos. Estas posibilidades no están
cubiertas en este tutorial.

- Escribir una aplicación personalizada utilizando uno


de las varias conexiones de PostgreSQL con lenguajes de
programación. Esta posibilidad se contempla en la parte IV.

Probablemente quieres arrancar psql para probar los


ejemplos de este tutorial. Lo puedes activar para la base de
datos mydb utilizando el siguiente comando:

$ psql mydb

Si no se especifica el nombre de la base de datos, entonces


utilizará por defecto el nombre de tu cuenta de usuario. Este
tema se discutió con anterioridad en la sección anterior.

13
www.todopostgresql.com

Si no se especifica el nombre de la base de datos, entonces


utilizará por defecto el nombre de tu cuenta de usuario. Este
ESTE LIBRO ES UN PROYECTO DE TRADUCCIÓN DEL MANUAL DE POSTGRESQL 13 QUE PUEDES ENCONTRAR EN POSTGRESQL.ORG

tema se discutió con anterioridad en la sección anterior.

En psql serás bienvenido con el siguiente mensaje:

psql (13beta1)
Type “help” for help.

mydb=>

La última línea también puede ser:

mydb=#

Esta última significará que eres un superusuario de la base de


datos, que sucederá en los casos en los instalas la instancia
PostgreSQL por ti mismo. Ser un superusuario significa que
no estás sujeto a controles de acceso. Para los propósitos de
este tutorial, esto no es importante.

Si tienes problemas arrancando psql, entonces ve a la sección


anterior. Los diagnósticos de createdb y psql son similares,
y las soluciones que funcionan para el primero deberían
funcionar también para el segundo.

La última línea impresa por psql es el prompt, e indica que


psql está listo para ser utilizado, puedes escribir cualquier
sentencia SQL en un entorno con psql. Prueba los siguientes
comandos:

14
www.todopostgresql.com
ESTE LIBRO ES UN PROYECTO DE TRADUCCIÓN DEL MANUAL DE POSTGRESQL 13 QUE PUEDES ENCONTRAR EN POSTGRESQL.ORG

mydb=> SELECT version();

version
---------------------------------------------------------------------
---------------------
PostgreSQL 13beta1 on x86_64-pc-linux-gnu, compiled by
gcc (Debian 4.9.2-10) 4.9.2, 64-bit
(1 row)

mydb=> SELECT current_date;

date
------
2016-01-07
(1 row)

mydb=> SELECT 2+2;


?column?
--------
4
(1 row)

El programa psql tiene un número de comandos internos que


no son comandos SQL. Estos empiezan con el carácter de la
barra invertida, “\”. Por ejemplo, puedes obtener ayuda en la
sintaxis de varios comandos SQL de PostgreSQL ejecutando:

mydb=> \h

15
www.todopostgresql.com

Para salir de psql, ejecuta:


ESTE LIBRO ES UN PROYECTO DE TRADUCCIÓN DEL MANUAL DE POSTGRESQL 13 QUE PUEDES ENCONTRAR EN POSTGRESQL.ORG

mydb=> \q

Tras el comando anterior, psql cerrará y regresarás tu terminal


habitual. (Para saber más comandos internos ejecuta \? antes
de salir.) Todas las funcionalidad y capacidades de psql están
documentadas en psql. En este tutorial no utilizaremos estas
características de forma explícita, pero puedes utilizarlas y
probarlas por ti mismo cuando sea de ayuda.

16
www.todopostgresql.com
ESTE LIBRO ES UN PROYECTO DE TRADUCCIÓN DEL MANUAL DE POSTGRESQL 13 QUE PUEDES ENCONTRAR EN POSTGRESQL.ORG

II

El lenguaje SQL

2.1 Introducción

Este capítulo da un pequeño repaso a cómo utillizar SQL


para realizar consultas simples. Este tutorial es únicamente
una introducción y no pretende ser un tutorial completo
del lenguaje SQL. Varias de las características propias de
PostgreSQL son únicamente extensiones al estándar.

En los ejemplos siguientes asumimos que has creado una


base de datos llamada mydb, tal y como se describió en el
capítulo anterior, y que has sido capaz de ejecutar psql.
Los ejemplos de este manual también los puedes encontrar
en los ficheros de tu instalación PostgreSQL, en el directorio;
src/tutorial. (Las distribuciones binarias de PostgreSQL no
cuentan con estos archivos.) Para utilizar estos archivos,
primero cambiaremos el directorio y luego ejecutaremos el
comando make:

$ cd …./src/tutorial
$ make

Estos comandos crean los scripts y compila los ficheros C


que contienen las funciones y tipos definidos por el usuario.
Por ello, para empezar este tutorial, ejecuta lo siguiente:

17
www.todopostgresql.com

$ cd …./tutorial
$ psql -s mydb
ESTE LIBRO ES UN PROYECTO DE TRADUCCIÓN DEL MANUAL DE POSTGRESQL 13 QUE PUEDES ENCONTRAR EN POSTGRESQL.ORG

mydb=> \i basics.sql

El comando \i lee los comandos del fichero especificado. La


opción -s pone el servicio en modo paso a paso, es decir,
pausa la ejecución antes de enviar cada consulta. Los
comandos usados en esta sección están disponibles en el
fichero basics.sql.

2.2 Conceptos

PostgreSQL es un Sistema de Administración de Bases de


Datos Relacionales. Esto significa que es un sistema creado
para administrar datos almacenados en relaciones. Una
relación es un término matemático para designar tabla. La
noción de almacenar datos en tablas puede parecer algo
bastante obvio al día de hoy, pero hay muchas formas de
organizar la información en bases de datos. Los archivos y
directorios en sistemas operativos Unix, por ejemplo forman
una base de datos organizada por jerarquías. Un enfoque
más moderno es el de una Base de Datos por objetos.

Cada tabla es una colección de filas. Cada fila de una tabla


tiene el mismo set de columnas, y cada columna almacena
un tipo de dato específico. Mientras que las columnas tienen
un orden fijo en cada fila, es importante recordar que SQL
no garantiza el orden de las filas dentro de la tabla, sin
embargo, estas pueden ser ordenadas explícitamente.

18
www.todopostgresql.com

Las tablas son agrupadas dentro de una base de datos, y una


colección de base de datos, administrada por una instancia
ESTE LIBRO ES UN PROYECTO DE TRADUCCIÓN DEL MANUAL DE POSTGRESQL 13 QUE PUEDES ENCONTRAR EN POSTGRESQL.ORG

de PostgreSQL constituye lo que llamamos un cluster de


base de datos.

2.3 Creando una nueva tabla

Puedes crear una nueva tabla especificando el nombre


de la tabla, junto con todos sus nombres de columna
y sus tipos:

Puedes escribir todo esto directamente en psql. No


importan los saltos de línea, psql reconocerá que el
comando no está terminado hasta encontrar el punto y
coma.

Los espacios en blanco pueden ser utilizados libremente


en SQL, espacios, tabuladores y saltos de línea. Esto quiere
decir que puedes escribir el comando alineado de forma
diferente al mostrado anteriormente, o incluso puedes
escribirlo todo en una sola línea. Dos guiones añaden un
comentario, cualquier cosa tras los dos guiones es ignorada
19
www.todopostgresql.com

hasta el final de la línea. SQL no es sensible a minúsculas y


mayúsculas, sin embargo podemos utilizar comillas dobles
ESTE LIBRO ES UN PROYECTO DE TRADUCCIÓN DEL MANUAL DE POSTGRESQL 13 QUE PUEDES ENCONTRAR EN POSTGRESQL.ORG

en los identificadores para mantener las mayúsculas en el


mismo.

varchar(80) especifica un tipo de dato que puede


almacenar cadenas de caracteres arbitrarios con una
longitud máxima de 80 caracteres. int es el dato normal de
números enteros. real es un tipo de dato para almacenar
números flotantes con precisión de un carácter. date, tipo
de dato utilizado para fechas.

PostgreSQL es compatible con los tipos de dato estándar


de SQL int, smallint, real, double, precision, char(N),
varchar(N), date, time, timestamp, e interval, así como
también otros tipos de utilidad general y un set rico
de tipos de dato geométrico.PostgreSQL puede ser
personalizable con un número arbitrario de tipos de datos
definidos por el usuario. Consecuentemente, los nombre
de los de los tipos de dato no son palabras claves en la
sintaxis, excepto donde se requiera asistencia ante casos
especiales del estándar SQL.

El siguiente ejemplo almacenará ciudades y su localización


geográfica asociada.

El tipo point es un ejemplo de un tipo de dato específico de

20
www.todopostgresql.com

PostgreSQL.
ESTE LIBRO ES UN PROYECTO DE TRADUCCIÓN DEL MANUAL DE POSTGRESQL 13 QUE PUEDES ENCONTRAR EN POSTGRESQL.ORG

Por último, si no necesitas más una tabla, o quieres hacerla de


nuevo de una forma diferente, puedes eliminarla utilizando
el siguiente comando:

DROP TABLE tablename;

2.4 Llenando una tabla de datos

El comando INSERT es utilizado para llenar las tablas de


datos.

INSERT INTO weather VALUES(‘San Francisco’, 46, 50,


0.25, ‘1994-11-27’);

Fíjate que todos los tipos de datos usan tipos de entrada


bastante obvios. Los constantes que no son valores numéricos
simples deben ir entre comillas simples, tal como muestra el
ejemplo. El tipo de dato fecha es bastante flexible a la hora
de aceptar valores de entrada, sin embargo para este tutorial
utilizaremos el formato mostrado aquí.
El tipo point requiere una entrada de datos en pareja, tal
como se muestra aquí:

INSERT INTO cities VALUES (‘San Francisco’, ‘(-194.0, 53.0)’);

La sintaxis utilizada hasta aquí requiere que recuerdes el

21
TODO
POSTGRESQL
.COM
FORMACIÓN POSTGRESQL
EN ESPAÑOL

MÁS DE 40 CURSOS,
APÚNTATE GRATIS
DURANTE 7 DÍAS

EL NETFLIX
DE POSTGRESQL

PULSA AQUÍ PARA DISFRUTAR TU OFERTA ESPECIAL


www.todopostgresql.com

orden de las columnas. Una sintaxis alternativa te permite


listar las columnas explícitamente.
ESTE LIBRO ES UN PROYECTO DE TRADUCCIÓN DEL MANUAL DE POSTGRESQL 13 QUE PUEDES ENCONTRAR EN POSTGRESQL.ORG

INSERT INTO weather (city, temp_lo, temp_hi, prcp, date)


VALUES (‘San Francisco’, 43, 57, 0.0, ‘1997-11-29’);

Puedes listar las columnas en un orden diferente. o incluso


omitir columnas. Por ejemplo, si no sabemos el valor de las
precipitaciones:

INSERT INTO weather (date, city, temp_hi, temp_lo)


VALUES (‘199-11-29’, ‘Hayward’, 54, 37);

Muchos desarrolladores consideran que listas las columnas


es una mucho mejor práctica que confiar simplemente en el
orden de las mismas.

Ingresa todos los comandos mostrados anteriormente, de


forma que tengas datos con los que trabajar en las siguientes
secciones.

También puedes haber utilizado el comando COPY para cargar


grandes cantidades de datos procedentes de ficheros de texto
plano. Usar el comando COPY en este caso es mucho más rápido
puesto que este comando ha sido optimizado para este uso. Un
ejemplo de utilización sería:

COPY weather FROM ‘/home/user/weather.txt’;

23
www.todopostgresql.com

El nombre del fichero debe estar disponible en la máquina


que ejecuta el proceso backend, no en el cliente, ya que el
ESTE LIBRO ES UN PROYECTO DE TRADUCCIÓN DEL MANUAL DE POSTGRESQL 13 QUE PUEDES ENCONTRAR EN POSTGRESQL.ORG

proceso lee directamente el fichero. Puedes aprender más


sobre este comando en la sección correspondiente.

2.5 Consultando una tabla

Para obtener datos de una tabla, decimos que la tabla es


consultada. El comando SQL utilizado para esto es el comando
SELECT. La sentencia de consulta está dividida en una parte
de selección, en donde seleccionamos las columnas que
queremos obtener en el resultado, una sección de tablas,
en donde se listan las tablas desde las cuales se obtendrá
la información, y una parte opcional de calificación, la parte
en donde se especifican las restricciones. Por ejemplo, para
obtener todas las filas de la tabla weather, escribimos:

SELECT * FROM weather;

Aquí el asterisco (*) es un atajo para decir ‘todas las columnas’.


Por lo que el mismo resultado se obtendría con:

SELECT city, temp_lo, temp_hi, prcp, date FROM weather;

La el resultado sería:

24
www.todopostgresql.com
ESTE LIBRO ES UN PROYECTO DE TRADUCCIÓN DEL MANUAL DE POSTGRESQL 13 QUE PUEDES ENCONTRAR EN POSTGRESQL.ORG

En la sección de selección puedes escribir expresiones, no


simplemente referencias a columnas. Por ejemplo, puedes
hacer:

SELECT city, (temp_hi+temp_lo)/2 AS temp_avg, date


FROM weather;

Esta consulta debería dar:

Fíjate cómo la cláusula AS es utilizada para reetiquetar la


columna de salida. La cláusula AS es opcional.

Una consulta puede ser “evaluada” añadiendo la cláusula


WHERE, esta especifica qué filas queremos. La cláusula WHERE
contiene una expresión Booleana (verdadero falso), y sólo son

25
www.todopostgresql.com

devueltas las filas para las cuales la expresión booleana es


verdadera. Los operadores booleanos tradicionales (AND, OR,
ESTE LIBRO ES UN PROYECTO DE TRADUCCIÓN DEL MANUAL DE POSTGRESQL 13 QUE PUEDES ENCONTRAR EN POSTGRESQL.ORG

and NOT) también son permitidos en la sección de calificación.


Por ejemplo, la siguiente consulta devuelve el clima de San
Francisco en días lluviosos:

SELECT * FROM weather


WHERE city = ‘San Francisco’ AND prcp > 0.0;

Resultado:

Puedes también solicitar que los resultados de una consulta


sean devueltos en orden:

SELECT * FROM weather


ORDER BY city;

26
www.todopostgresql.com

En este ejemplo el orden no está especificado completamente,


por lo que puedes encontrar la fila de San Francisco en cualquier
ESTE LIBRO ES UN PROYECTO DE TRADUCCIÓN DEL MANUAL DE POSTGRESQL 13 QUE PUEDES ENCONTRAR EN POSTGRESQL.ORG

lugar. Pero siempre te encontrarás con la tabla anterior si


ejecutas la siguiente consulta:

SELECT * FROM weather


ORDER BY city, temp_lo;

Puedes también especificar que no quieres filas repetidas


en el resultado de la consulta:

SELECT DISTINCT city FROM weather;

Una vez más, el resultado de esta consulta puede variar.


Sin embargo, puedes asegurarte resultados consistentes
utilizando DISTINCT y ORDER BY en la misma consulta:

SELECT DISTINCT city


FROM weather
ORDER BY city;

27
www.todopostgresql.com

2.6 Joins entre tablas


ESTE LIBRO ES UN PROYECTO DE TRADUCCIÓN DEL MANUAL DE POSTGRESQL 13 QUE PUEDES ENCONTRAR EN POSTGRESQL.ORG

Hasta ahora, nuestras consultas han accedido únicamente


a una tabla al mismo tiempo. Sin embargo, las consultas
pueden acceder a múltiples tablas a la vez, o bien acceder y
procesar la información de varias columnas de una misma
tabla. Una consulta que ejecuta una acción de este tipo es
llamada una consulta Join. Por ejemplo, digamos que quieres
listar todos los registros de del clima junto con la localización
de la ciudad asociada. Para hacer esto necesitamos
comparar la la columna city de cada fila de la tabla weather
con la columna name de todas las filas en la tabla cities, y
seleccionar los pares de filas donde estos valores coinciden.

NOTA
Este es sólo un modelo conceptual. Una consulta join habitualmente
se ejecuta en una forma más eficiente que comparando cada
posible par de filas, pero esto es invisible al usuario.

Nuestro último ejemplo sería realizado por la siguiente


consulta:

SELECT *
FROM weather, cities
WHERE city = name;

28
www.todopostgresql.com

Observa dos cosas sobre este resultado:


ESTE LIBRO ES UN PROYECTO DE TRADUCCIÓN DEL MANUAL DE POSTGRESQL 13 QUE PUEDES ENCONTRAR EN POSTGRESQL.ORG

- No existe fila para la ciudad de Hayward. Esto ha


ocurrido porque en la tabla cities no existe fila para la ciudad
Hayward, por lo que el join ignora las filas sin coincidencias
en la tabla weather. Veremos cómo podemos solucionar
esto.

- Hay dos columnas que contienen el nombre de la


ciudad. Esto es correcto porque la lista de columnas de las
tablas weather y cities están concatenadas. En la práctica,
esto es indeseable, por lo que probablemente querrás listar
las columnas explícitamente antes que usar *.

SELECT city, temp_lo, temp_hi, prcp, date, location


FROM weather, cities
WHERE city = name;

EJERCICIO:

Intenta determinar la semántica de esta


consulta cuando la cláusula WHERE es
eliminada.

Ya que todas las columnas tienen nombres diferentes, el


parseador encontrará automáticamente la tabla a la que
pertenece cada una. Si hubiesen nombres duplicados en las
dos tablas necesitarás calificar los nombres de las columnas
para mostrar la columna correcta:

29
www.todopostgresql.com

SELECT weather.city, weather.temp_lo, weather.temp_hi,


weather.prcp, weather.date, cities.location FROM weather,
ESTE LIBRO ES UN PROYECTO DE TRADUCCIÓN DEL MANUAL DE POSTGRESQL 13 QUE PUEDES ENCONTRAR EN POSTGRESQL.ORG

cities WHERE cities.name = weather.city;

Se considera una buena práctica el calificar el nombre de


todas las columnas en una consulta join, de forma que la
consulta no falle si en el futuro se añade una columna con el
nombre duplicado a alguna de las tablas.

Las consultas que acabamos de ver pueden ser escritas


también de una forma alternativa:

SELECT *
FROM weather INNER JOIN cities ON (weather.city =
cities.name);

Esta sintaxis no es muy común como las anteriores, sin


embargo la mostramos aquí para que puedas entender los
siguientes conceptos.

Ahora veremos cómo podemos obtener los registros de


Hayward de nuevo en el set de resultados. Lo que queremos
que la consulta haga es escanear la tabla weather y
para cada fila encontrar el registro de la tabla cities que
coincide. Si no se encuentra una coincidencia, queremos
“resultados vacíos” para sustituirse por las columnas de
la tabla cities. Este tipo de consulta es llamada outer join.
Los joins vistos hasta ahora son inner joins. El comando
sería el siguiente:

30
www.todopostgresql.com

SELECT *
FROM weather LEFT OUTER JOIN cities ON
ESTE LIBRO ES UN PROYECTO DE TRADUCCIÓN DEL MANUAL DE POSTGRESQL 13 QUE PUEDES ENCONTRAR EN POSTGRESQL.ORG

(weather.city = cities.name);

Esta consulta se llama left outer porque la tabla mencionada


a la izquierda del operador join tendrá al menos una vez
cada una de sus filas en el resultado, mientras que la tabla
de la derecha tendrá solo aquellas filas que coinciden con los
resultados de la izquierda. Cuando tenemos resultados en la
la tabla de la izquierda, pero no tenemos una coincidencia en
la tabla de la derecha, entonces las columnas de la derecha
son sustituidos por valores nulos.

EJERCICIO:

También tenemos right outer joins, y full


outer joins. Descubre qué hacen estos
comandos.

También podemos hacer una consulta join en contra

31
www.todopostgresql.com

de sí misma. Es lo que llamamos una consulta self join.


Por ejemplo, supón que queremos encontrar todos los
ESTE LIBRO ES UN PROYECTO DE TRADUCCIÓN DEL MANUAL DE POSTGRESQL 13 QUE PUEDES ENCONTRAR EN POSTGRESQL.ORG

registros de weather que están en un rango de temperatura


de otros registros de weather. Para esto necesitaremos
comparar las columnas temp_lo y temp_hi de cada registro
de weather con las columnas temp_lo y temp_hi de otros
registros de weather. Podemos hacer esto con la consulta
siguiente:

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;

En esta consulta hemos reetiquetado la tabla weather como


W1 y W2 para ser capaces de distinguir el lado izquierdo del
derecho en el join. Puedes utilizar este tipo de alias en otras
queries para ahorrarte algo de escritura. Por ejemplo:

SELECT *
FROM weather w, cities c
WHERE w.city = c.name;

32
www.todopostgresql.com

Este estilo es bastante es frecuente y te lo encontrarás muy a


menudo.
ESTE LIBRO ES UN PROYECTO DE TRADUCCIÓN DEL MANUAL DE POSTGRESQL 13 QUE PUEDES ENCONTRAR EN POSTGRESQL.ORG

2.7 Funciones agregadas

Como la mayoría de gestores de Bases de Datos, PostgreSQL


soporta funciones agregadas. Una función agregada calcula
un resultado único a partir de datos provenientes de
múltiples filas. Por ejemplo, hay funciones agregadas para
calcular una cuenta de coincidencias, count, una suma, sum,
un promedio, avg, el valor máximo, max, el valor mínimo,
min, de una serie de valores.

Como ejemplo, podemos encontrar el valor máximo de las


temperaturas mínimas con la siguiente consulta:

SELECT max(temp_lo) FROM weather;

Si queríamos conocer cuál ciudad, o ciudades que


coinciden con la consulta anterior, podríamos probar con la
siguiente consulta:

SELECT city FROM weather WHERE temp_lo = max(temp_lo);

33
www.todopostgresql.com

pero esta consulta no funcionará ya que la función


agregada max no puede ser utilizada dentro de la cláusula
ESTE LIBRO ES UN PROYECTO DE TRADUCCIÓN DEL MANUAL DE POSTGRESQL 13 QUE PUEDES ENCONTRAR EN POSTGRESQL.ORG

WHERE. Esta restricción es debida a que la cláusula WHERE


determina las filas que serán incluidas en el cálculo del
agregado; por lo que obviamente la cláusula WHERE es
evaluada antes de que las funciones agregadas sean
calculadas. Sin embargo, como en la mayoría de los casos,
la consulta puede ser reestructurada para obtener el
resultado deseado, en este caso usando una subconsulta:

SELECT city FROM weather


WHERE temp_lo = (SELECT max(temp_lo) FROM
weather);

En este caso el resultado es satisfactorio porque la


subquery es un cálculo independiente que calcula la
función agregada por su cuenta y de forma separada a lo
que está ocurriendo en la consulta externa.

Las funciones agregadas también son muy útiles en


combinación con sentencias GROUP BY. Por ejemplo,
podemos conseguir el máximo de las temperaturas
mínimas observadas en cada ciudad con:

SELECT city, max(temp_lo)


FROM weather
GROUP BY city;

34
www.todopostgresql.com
ESTE LIBRO ES UN PROYECTO DE TRADUCCIÓN DEL MANUAL DE POSTGRESQL 13 QUE PUEDES ENCONTRAR EN POSTGRESQL.ORG

La consulta anterior nos devuelve una fila por ciudad. Cada


agregado es calculado sobre las filas que coinciden con esa
ciudad. Podemos filtrar estos resultados utilizando HAVING:

SELECT city, max(temp_lo)


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

Esta consulta nos da el mismo resultado que la anterior,


pero sólo muestra las ciudades con temp_lo bajo 40.

SELECT city, max(tempo_lo)


FROM weather
WHERE city LIKE ‘S%’
GROUP BY city
HAVING max(temp_lo) < 40;

El operador LIKE realiza un emparejamiento por patrón, y


será explicado luego.

35
www.todopostgresql.com

Es muy importante entender la interacción entre las


funciones agregadas y los comandos SQL, WHERE y HAVING.
ESTE LIBRO ES UN PROYECTO DE TRADUCCIÓN DEL MANUAL DE POSTGRESQL 13 QUE PUEDES ENCONTRAR EN POSTGRESQL.ORG

La diferencia fundamental entre WHERE y HAVING es la


siguiente:

WHERE selecciona las filas antes de que los grupos y las


funciones agregadas sean calculadas (así pues se controla qué
filas y datos van dentro del cálculo de la función agregada),
mientras que HAVING selecciona grupos de filas después
de que los grupos y las funciones agregadas hayan sido
calculadas. Así pues, la cláusula WHERE no debe contener
funciones agregadas; no tiene sentido intentar utilizar
una función agregada para determinar qué filas serán
utilizadas en el cálculo de una función agregada. Por otro
lado, la cláusula HAVING siempre contiene funciones
agregadas. Hablando estrictamente, puedes utilizar la
cláusula HAVING sin utilizar funciones agregadas, pero
esto raramente es útil. La misma sentencia utilizando
WHERE sería mucho más eficiente.

En el ejemplo anterior, podemos utilizar la restricción del


nombre de la ciudad en la cláusula WHERE, ya que esta no
necesita funciones agregadas. Sería mucho más eficiente
que añadir la restricción a HAVING , ya que evitamos así el
agrupamiento y el cálculo de los agregados para todas las
filas que fallen el el test de WHERE.

2.8 Updates

Puedes actualizar columnas existentes utilizando el comando


UPDATE. Imagina que descubrimos que los datos de la lectura
de temperatura en realidad son 2 grados menos a partir del
28 de Noviembre. Puedes corregir los datos con la sentencia
siguiente:
36
www.todopostgresql.com

UPDATE weather
SET temp_hi = temp_hi -2, temp_lo = temp_lo -2
ESTE LIBRO ES UN PROYECTO DE TRADUCCIÓN DEL MANUAL DE POSTGRESQL 13 QUE PUEDES ENCONTRAR EN POSTGRESQL.ORG

WHERE date > ‘1994-11-28’;

Echemos un vistazo al estado de los datos tras esta


actualización:

SELECT * FROM weather;

2.9 Borrados

Las filas pueden ser eliminadas de una tabla utilizando el


comando DELETE. Imagina que ya no tienes interés en el
clima de Hayward, en ese caso puedes utilizar el siguiente
comando para borrar esas filas de la tabla:

DELETE FROM weather WHERE city = ‘Hayward’;

Tras el comando anterior, todas las filas que pertenecían a

37
www.todopostgresql.com

Hayward han sido borradas.


ESTE LIBRO ES UN PROYECTO DE TRADUCCIÓN DEL MANUAL DE POSTGRESQL 13 QUE PUEDES ENCONTRAR EN POSTGRESQL.ORG

SELECT * FROM weather;

Debes tener mucho cuidado de las sentencias con la forma:

DELETE FROM tablename;

Si no existe ninguna restricción, la sentencia DELETE borra


todas las filas de la tabla dada, dejándola vacía. El sistema
no requerirá ningún tipo de confirmación antes de ejecutar
esta tarea.

38
www.todopostgresql.com
ESTE LIBRO ES UN PROYECTO DE TRADUCCIÓN DEL MANUAL DE POSTGRESQL 13 QUE PUEDES ENCONTRAR EN POSTGRESQL.ORG

III

Características avanzadas

3.1 Introducción

En el capítulo anterior hemos visto los fundamentos del


uso de SQL para almacenar datos en PostgreSQL. Ahora
veremos algunas características avanzadas de SQL que
simplificarán el manejo y la prevención de pérdida de datos
o la corrupción de los mismos. Por último aprenderemos
algunas de las extensiones PostgreSQL.

Este capítulo hará varias referencias a los ejemplos del capítulo


2, bien para cambiarlos o bien para mejorarlos, por lo que
será muy recomendable haber leído este capítulo y haber
comprendido esos ejemplos. Algunos de los ejemplos aquí
expuestos también podrán ser encontrados en el directorio
advanced.sql. Este fichero incluye también algunos datos
a incluir en nuestra base de datos. Si necesitas ayuda para
utilizar el fichero, revisa la sección 2.1.

3.2 Vistas

Recuerda las consultas hechas en la sección 2.6. Imagina


que el listado combinado de registros de clima y la
localización de la ciudad es de interés especial para tu
aplicación, pero no quieres escribir la consulta cada vez
que la necesitas. En estos casos puedes crear una vista a
partir de la consulta, la vista le da un nombre a la consulta

39
www.todopostgresql.com

y puedes referirte a ella como si lo hicieses a una tabla


ordinaria.
ESTE LIBRO ES UN PROYECTO DE TRADUCCIÓN DEL MANUAL DE POSTGRESQL 13 QUE PUEDES ENCONTRAR EN POSTGRESQL.ORG

CREATE VIEW myview AS


SELECT city, temp_lo, temp_hi, prcp, date, location
FROM weather, cities
WHERE city = name;

SELECT * FROM myview;

Poder hacer uso de vistas de forma sencilla es un aspecto


fundamental del diseño de Bases de Datos SQL. Las vistas
te permiten encapsular los detalles de la estructura de
tus tablas, cosa que puede cambiar según evolucione tu
aplicación, detrás de interfaces consistentes.

Las vistas pueden ser utilizadas en lugar de la tabla real


casi siempre. Construir vistas a partir de otras vistas no es
común.

3.3 Foreign keys

Recuerda las tablas weather y cities del capítulo 2. Considera


ahora el siguiente problema:

Quieres asegurarte de que nadie inserte filas en la tabla


weather que no tengan una correspondencia en la tabla
cities.esto se llama mantener una integridad referencial
en tus datos. En una base de datos muy simple, eso se
implementaría, si está siendo implementado, revisando
primero la existencia de una coincidencia en la tabla cities,
y luego insertando o rechazando el nuevo registro en la
40
www.todopostgresql.com

tabla weather. Este enfoque tiene varios problemas y no es


exactamente lo más cómodo, por lo que PostgreSQL puede
ESTE LIBRO ES UN PROYECTO DE TRADUCCIÓN DEL MANUAL DE POSTGRESQL 13 QUE PUEDES ENCONTRAR EN POSTGRESQL.ORG

hacerlo por ti.

La nueva declaración de tablas sería la siguiente:

CREATE TABLE cities (


city varchar(80) primary key,
location point
);

CREATE TABLE weather (


city varchar(80) references cities(city),
temp_lo int,
temp_hi int,
prcp real,
date date,
);

Ahora intenta insertar un registro inválido.

INSERT INTO weather VALUES (‘Berkeley’, 45, 53, 0.0,


‘1994-11-28’);

ERROR: insert or update on table “weather” violates foreign key


constraint “weather_city_fkey”
DETAIL: Key (city)=(Berkeley) is not present in table “cities”.

El comportamiento de foreign keys puede ser ajustado a la


perfección a tu aplicación. No profundizaremos más en este
tutorial, pero sí hacemos referencia al capítulo 5 para más

41
TODO
POSTGRESQL
.COM
FORMACIÓN POSTGRESQL
EN ESPAÑOL

MÁS DE 40 CURSOS,
APÚNTATE GRATIS
DURANTE 7 DÍAS

EL NETFLIX
DE POSTGRESQL

PULSA AQUÍ PARA DISFRUTAR TU OFERTA ESPECIAL


www.todopostgresql.com

información. Un uso adecuado de foreign keys mejorará sin


duda la calidad de tus aplicaciones y base de datos, por lo
ESTE LIBRO ES UN PROYECTO DE TRADUCCIÓN DEL MANUAL DE POSTGRESQL 13 QUE PUEDES ENCONTRAR EN POSTGRESQL.ORG

que te animamos a aprender más sobre el tema.

3.4 Transacciones

Las transacciones son un concepto fundamental en todos los


sistemas gestores de Bases de Datos. El punto esencial de
una transacción es que agrupa múltiples pasos en uno solo,
es una operación de todo o nada. Los estados intermedios
entre cada parte de la transacción no son visibles para otras
transacciones coincidentes, y si algún fallo en estos pasos
evita que la transacción se complete, entonces ninguno de
los pasos anteriores afecta a la base de datos.

Por ejemplo, considera una base de datos de un banco


que contiene los balances de varias cuentas de clientes,
así también como los balances de los depósitos totales por
sucursal (branch). Supongamos que queremos registrar un
pago de $100.00 de la cuenta de Alice a la cuenta de Bob.
Simplificando mucho, los comandos SQL para ejecutar esta
transacción serían los siguientes:

UPDATE accounts SET balance = balance - 100.00


WHERE name = ‘Alice’;
UPDATE branches SET balance = balance - 100.00
WHERE name = (SELECT branch_name FROM accounts
WHERE name = ‘Alice’);
UPDATE accounts SET balance = balance + 100.0
WHERE name = ‘’Bob;
UPDATE branches SET balance = balance + 100.00
WHERE name = (SELECT branch_name FROM accounts
WHERE name = ‘Bob’);
43
www.todopostgresql.com

Los detalles de estos comandos no son importantes en


esta ocasión; el punto importante ahora es que tenemos
ESTE LIBRO ES UN PROYECTO DE TRADUCCIÓN DEL MANUAL DE POSTGRESQL 13 QUE PUEDES ENCONTRAR EN POSTGRESQL.ORG

varias actualizaciones separadas, pero relacionadas, para


conseguir esta operación. Nuestro jefe de banco querrá
estar seguro de que bien estas operaciones ocurren al
unísono, o bien no ocurre ninguna. No queremos que Bob
reciba un dinero que no ha sido descontado de la cuenta de
Alice, así como tampoco queremos que Alice deje de tener
un dinero que no aparece en la cuenta de Bob. necesitamos
una garantía de que si algo va mal durante la ejecución de
estas actualizaciones, la ejecución de las mismas se detenga
y que ninguno de los pasos dados hasta el momento del error
tengan un efecto permanente. Agrupar las actualizaciones en
una transacción nos da la garantía que estamos buscando. Se
dice que una transacción es atómica: desde el punto de vista
de otras transacciones, esta debe suceder por completo o
no suceder.

También queremos una garantía de que una vez la


transacción se haya completado y haya sido reconocida
por el sistema gestor de base de datos, ésta efectivamente
se haya registrado permanentemente y que no se perderá
nada de la información incluso si ocurre algún problema
un poco después de finalizar la transacción. Por ejemplo,
si estamos registrando una retirada de efectivo de Bob,
no queremos que el registro se débito se desaparezca
por alguna razón justo cuando él ha salido de la sucursal.
una base de datos transaccional garantiza que todas las
actualizaciones hechas por una transacción son registradas
permanentemente antes de que se reporten como
completas.

Otra de las características importantes de las bases


de datos transaccionales está muy relacionada con el
concepto de actualizaciones atómicas: cuando múltiples

44
www.todopostgresql.com

transacciones se están ejecutando de forma concurrente,


cada una de ellas no debería ser capaz los cambios
ESTE LIBRO ES UN PROYECTO DE TRADUCCIÓN DEL MANUAL DE POSTGRESQL 13 QUE PUEDES ENCONTRAR EN POSTGRESQL.ORG

intermedios realizados por las otras. Por ejemplo, si


una transacción está ocupada calculando el total de los
balances de todas las sucursales, esta no tendrá en cuenta
ni la operación de débito de Alice ni tampoco el ingreso en la
cuenta de Bob, o viceversa- Por lo tanto, las transacciones
deben ser todo o nada, no solo cuando hablamos de su
permanencia en su propia base de datos, sino también
en términos de visibilidad. Las actualizaciones hechas
hasta ese momento por otra transacción en proceso son
invisibles a otras transacciones hasta que la transacción
se completa, es entonces cuando todas las actualizaciones
se hacen visibles simultáneamente.

En PostgreSQL, definimos una transacción rodeando las


sentencias SQL que la compondrán con los comandos BEGIN
y COMMIT. Por lo tanto nuestra transacción bancaria en
realidad se verá de la siguiente forma:

BEGIN;
UPDATE accounts SET balance = balance - 100.00
WHERE name = ‘Alice’;
-- etc etc
COMMIT;

Si en medio de la transacción decidimos que no queremos


realmente continuar con la misma, quizás vemos que el saldo
de Alice es negativo, entonces podemos utilizar el comando
ROLLBACK en lugar de COMMIT, y todas las actualizaciones
serán canceladas.

PostgreSQL en realidad trata cada sentencia SQL como

45
www.todopostgresql.com

si estuviese ejecutando dentro de una transacción. Si no


declaras el comando BEGIN, entonces cada sentencia
ESTE LIBRO ES UN PROYECTO DE TRADUCCIÓN DEL MANUAL DE POSTGRESQL 13 QUE PUEDES ENCONTRAR EN POSTGRESQL.ORG

individual tiene un BEGIN y, si todo va bien, COMMIT implícito.


Un grupo de sentencias rodeadas por un BEGIN y COMMIT,
también es conocido como un bloque de transacciones.

NOTA: Las librerías de algunos clientes ejecutan los comandos BEGIN


y COMMIT automáticamente, de forma que puedas tener los efectos
de un bloque de transacción sin preguntar. Revisa la documentación
del cliente que estés utilizando.

Es posible controlar las sentencias que componen una


transacción en una forma más granular mediante el uso de
savepoints. Un savepoint te permite descartar selectivamente
partes de la transacción, mientras guardas el resto. Después
de definir un savepoint utilizando SAVEPOINT, si es necesario
puedes volver hasta el savepoint utilizando ROLL BACK TO; en
este caso todos los cambios realizados entre la definición del
savepoint y el rolling back son descartados, y nos quedamos
únicamente con los anteriores a la definición del savepoint.

Luego de haber regresado hasta nuestro savepoint podemos


bien conservarlo o borrarlo, según las necesidades que
tengamos. Si lo conservamos podemos volver a él tantas
veces como necesitemos, si lo borramos estaremos
liberando algunos recursos. Recuerda que bien si liberamos
o volvemos a un savepoint, automáticamente eliminaremos
todos savepoints que estaban definidos después.

Recuerda que todo esto está pasando dentro de un bloque


de transacción, por lo que nada de esto es visible para otras
sesiones de la base de datos. Solo cuando el bloque termina
adecuadamente, los cambios permanentes son visibles

46
www.todopostgresql.com

como una unidad para otras sesiones. Así también debes


saber que las transacciones de ROLL BACK nunca son visibles.
ESTE LIBRO ES UN PROYECTO DE TRADUCCIÓN DEL MANUAL DE POSTGRESQL 13 QUE PUEDES ENCONTRAR EN POSTGRESQL.ORG

Recordando la Base de datos del banco, supongamos que


pasamos $100.00 de la cuenta de Alice a la cuenta de Bob,
después nos damos cuenta que debimos haber ingresado
ese dinero en la cuenta de Wally. Pudimos haber realizado
esta operación utilizando savepoints:

BEGIN;
UPDATE accounts SET balance = balance - 100.00
WHERE name = ‘Alice’;
SAVEPOINT my_savepoint;
UPDATE accounts SET balance = balance + 100.00
WHERE name = ‘Bob’;
-- oops … forget that and use Wally’s account
ROLLBACK TO my_savepoint;
UPDATE accounts SET balance = balance + 100.00
WHERE name = ‘Wally’;
COMMIT;

Este ejemplo es, obviamente, muy simple, sin embargo


es útil para ejemplificar todo el control que podemos
ejercer en un bloque de transacciones mediante el uso de
savepoints. Además, ROLLBACK TO, es la única forma de
volver a controlar un bloque de transacciones que ha sido
abortado por el sistema debido a un error, puede evitarnos
volver a empezar el proceso de cero.

47
www.todopostgresql.com

3.5 Funciones ventana


ESTE LIBRO ES UN PROYECTO DE TRADUCCIÓN DEL MANUAL DE POSTGRESQL 13 QUE PUEDES ENCONTRAR EN POSTGRESQL.ORG

Una función ventana realiza un cálculo en un set de filas


que están relacionadas de alguna manera a la fila actual.
Es comparable al tipo de cálculo que puede ser hecho con
una función agregada. Sin embargo, las funciones ventana
no provocan un agrupamiento en una única fila de salida,
como sí lo haría una función agregada. Cada fila mantiene
su identidad separa. Detrás de cámara, lo que sucede es que
una función ventana es capaz de acceder a más de la fila de
resultado.

Aquí tenemos un ejemplo que muestra cómo comparar el


salario de cada empleado con la media en su departamento:

SELECT depname, empno, salary, avg(salary) OVER (PARTITION


BY depname) FROM empsalary;

48
www.todopostgresql.com

Las tres primeras columnas provienen directamente de


la tabla empsalary, y tenemos una fila en el resultado por
ESTE LIBRO ES UN PROYECTO DE TRADUCCIÓN DEL MANUAL DE POSTGRESQL 13 QUE PUEDES ENCONTRAR EN POSTGRESQL.ORG

cada fila existente en la tabla. La cuarta columna representa


un promedio de todas las filas que tienen el mismo
departamento que la fila de resultado. En realidad se trata
de la misma función agregada avg, pero el comando OVER
causa que sea tratada como una función ventana y calcule
los resultados de esta forma.

Una función ventana siempre contiene la cláusula OVER


siguiendo el nombre de la función y sus argumentos. Esto
es lo que la caracteriza y diferencia sintácticamente de
una función agregada normal. La cláusula OVER determina
exactamente como las filas de la consulta serán separadas
para calcular la función ventana. La cláusula PARTITION BY
junto con OVER divide las filas en grupos, o particiones,
que comparten los mismos valores de la expresión que
contiene PARTITION BY. Para cada fila, la función ventana
es calculada en todas filas que comparten la partición de la
fila actual.

También puedes controlar el orden en el que las filas son


procesadas por funciones ventana mediante el uso de
ORDER BY junto con OVER. La ventana ORDER BY no tiene
por qué coincidir con el orden de las filas del resultado. Por
ejemplo:

SELECT depname, empno, salary, rank() OVER (PARTITION BY


depname ORDER BY salary DESC) FROM empsalary;

49
www.todopostgresql.com
ESTE LIBRO ES UN PROYECTO DE TRADUCCIÓN DEL MANUAL DE POSTGRESQL 13 QUE PUEDES ENCONTRAR EN POSTGRESQL.ORG

Como se muestra aquí, la función rank produce un rango


numérico para cada valor distinto de ORDER BY en la fila
actual de la partición, estamos usando el orden definido
por ORDER BY. La función rank no necesita un parámetro
explícito, porque su comportamiento es determinado por la
cláusula OVER.

Las filas consideradas por una función ventana son aquellas


de una “tabla virtual” que ha sido producida por la consulta
realizada con FROM y filtrada por WHERE, GROUP BY, y
HAVING, si existe algún filtro. Por ejemplo, una fila que no
se incluye en el resultado de la consulta porque no cumple
los requerimientos establecidos por la cláusula WHERE no
será tenida en cuenta para ninguna función ventana. Una
consulta puede contener múltiples funciones ventana que
dividan los datos de la tabla original en diferentes formas

50
www.todopostgresql.com

mediante diferentes cláusulas OVER, pero todas actuarán en


el resultado definido en la “tabla virtual”.
ESTE LIBRO ES UN PROYECTO DE TRADUCCIÓN DEL MANUAL DE POSTGRESQL 13 QUE PUEDES ENCONTRAR EN POSTGRESQL.ORG

Ya hemos visto que podemos omitir la cláusula ORDER BY


si el orden de las filas no es importante. También es posible
omitir la cláusula PARTITION BY, en este caso habrá una
única partición que incluirá a toda la “tabla virtual”.

Existe otro concepto importante asociado con las funciones


ventana: para cada fila existe un conjunto de filas dentro la
partición que es llamado el marco ventana. Alguna funciones
ventana actúan únicamente en las filas del marco ventana en
lugar de hacerlo en toda la partición. Por defecto, si tenemos
una sentencia ORDER BY entonces el marco ventana consiste
en todas las filas, desde el principio de la partición hasta la
fila actual, incluyendo todas las filas siguientes que tengan
el mismo valor de acuerdo a la cláusula ORDER BY. Cuando
la cláusula ORDER BY se ha omitido, el marco por defecto
consiste en todas las filas de la partición. A continuación
tenemos un ejemplo usando sum:

SELECT salary, sum(salary), OVER() FROM empsalary;

51
www.todopostgresql.com

En esta consulta como no hay ORDER BY en la cláusula


OVER, el marco ventana es el mismo que la partición, que
ESTE LIBRO ES UN PROYECTO DE TRADUCCIÓN DEL MANUAL DE POSTGRESQL 13 QUE PUEDES ENCONTRAR EN POSTGRESQL.ORG

debido a la falta de PARTITION BY es la tabla entera; en


otras palabras, cada suma es realizada en la tabla entera,
de forma que tenemos el mismo resultado para cada fila. Si
añadimos una cláusula ORDER BY, conseguiremos resultados
completamente diferentes:

SELECT salary, sum(salary) OVER (ORDER BY salary)


FROM empsalary;

En esta ocasión la suma se realiza desde el primer salario


(el más bajo) hasta el actual, incluyendo cualquier duplicado
del actual (fíjate los resultados para los salarios duplicados).

Las funciones ventana están permitidas solo en la lista


resultante de la consulta SELECT y ORDER BY. Están
prohibidas en cualquier otro caso, como con GROUP BY,
HAVING y WHERE, esto ocurre porque, lógicamente las
funciones ventana se ejecutan después del proceso de

52
www.todopostgresql.com

estas cláusulas. También, las funciones ventana se ejecutan


después de las funciones agregadas normales. Esto último
ESTE LIBRO ES UN PROYECTO DE TRADUCCIÓN DEL MANUAL DE POSTGRESQL 13 QUE PUEDES ENCONTRAR EN POSTGRESQL.ORG

significa que es válido incluir una función agregada en los


argumentos de una función ventana, pero no vice versa. Si
tienes la necesidad de filtrar o agrupar filas después de que
los cálculos de la función ventana se han realizado, puedes
utilizar una consulta sub-select.

SELECT depname, empno, salary, enroll_date


FROM
(SELECT depname, empno, salary, enroll_date,
rank() OVER (PARTITION BY depname ORDER BY salary
DESC,
empno) AS pos
FROM empsalary)
AS ss
WHERE pos < 3;

Esta última consulta muestra las filas de la consulta interior


que tienen un rango menor que 3.

Cuando una consulta utiliza múltiples funciones ventana, es


posible escribir cada una con una cláusula OVER separada. Sin
embargo, esta práctica puede producir errores y duplicados
si la misma “tabla virtual” es requerida para varias funciones.
En ese caso, podemos llamar a cada “tabla virtual” con la
cláusula WINDOW y entonces ser referenciada en la cláusula
OVER. Por ejemplo:

SELECT sum(salary) OVER w, avg(salary) OVER w


FROM empsalary
WINDOW w AS (PARTITION BY depname ORDER BY
salary DESC);

53
www.todopostgresql.com

3.6 Herencia
ESTE LIBRO ES UN PROYECTO DE TRADUCCIÓN DEL MANUAL DE POSTGRESQL 13 QUE PUEDES ENCONTRAR EN POSTGRESQL.ORG

La herencia es un concepto las bases de datos orientadas


a objetos. Este concepto abre la puerta a interesantes
posibilidades en el diseño de una base de datos.

Vamos a crear dos tablas: Una tabla cities y una tabla


capitals. Naturalmente, las capitales son también ciudades,
por lo que quieres alguna forma de mostrar las capitales
implícitamente cuando listas todas las ciudades. Si eres
intuitivo puedes llegar a una sentencia como la siguiente:

CREATE TABLE capitals (


name text,
population real,
elevation int, --(in ft)
state char(2)
);

CREATE TABLE non_capitals(


name text,
population real,
elevation int --(in ft)
);

CREATE VIEW AS
SELECT name, population, elevation FROM capitals
UNION
SELECT name, population, elevation FROM non_
capitals;

Esta sentencia trabaja bien cuando hablamos de consultar


datos, sin embargo no funciona de la misma forma cuando

54
www.todopostgresql.com

necesitamos actualizar múltiples filas.


ESTE LIBRO ES UN PROYECTO DE TRADUCCIÓN DEL MANUAL DE POSTGRESQL 13 QUE PUEDES ENCONTRAR EN POSTGRESQL.ORG

Una solución mejor sería la siguiente:

CREATE TABLE cities (


name text,
population real,
elevation int --(in ft)
);

CREATE TABLE capitals (


state char(2)
) INHERITS (cities);

En este caso, una fila de capitals hereda todas las columnas


(name, population, and elevation) de su padre, cities. El
tipo de dato de la columna name es text, un tipo nativo de
PostgreSQL para strings de longitud variable. Las capitales
tienen una columna extra, state, que muestra el estado al
que pertenecen. En PostgreSQL, una tabla puede heredar de
cero o más tablas.

Por ejemplo, la siguiente consulta encuentra los nombres de


todas las ciudades, incluyendo las capitales de estado, que
están localizadas a una elevación superior a 500 pies.

SELECT name, elevation


FROM cities
WHERE elevation > 500;

55
www.todopostgresql.com

Que devuelve:
ESTE LIBRO ES UN PROYECTO DE TRADUCCIÓN DEL MANUAL DE POSTGRESQL 13 QUE PUEDES ENCONTRAR EN POSTGRESQL.ORG

Por otra parte, la siguiente consulta encuentra todas las


ciudades que no son capitales y están localizadas a una
elevación superior a 500 pies:

SELECT name, elevation


FROM ONLY cities
WHERE elevation > 500;z

En esta ocasión el ONLY antes de cities indica que la consulta


debe ejecutarse únicamente en la tabla cities, y no en las
tablas que están por debajo de cities en la jerarquía de
herencia. Varios de los comandos que hemos visto hasta
ahora, SELECT, UPDATE, DELETE, soportan la notación ONLY.

NOTA: Aunque la herencia es útil frecuentemente, no ha sido


integrada con restricciones únicas o foreign keys, lo que limita su
usabilidad.

56
www.todopostgresql.com

3.7 Conclusión
ESTE LIBRO ES UN PROYECTO DE TRADUCCIÓN DEL MANUAL DE POSTGRESQL 13 QUE PUEDES ENCONTRAR EN POSTGRESQL.ORG

PostgreSQL tiene muchas más características que no han


sido tratadas en este tutorial introductorio, que ha sido
orientado completamente a nuevos usuarios de SQL. Estas
características adicionales son tratadas con mucho más
detalle en nuestros cursos y artículos en TodoPostgreSQL.
com . Si necesitas más material introductorio, por favor visita
nuestra web o la web oficial de PostgreSQL.

57
TODO
POSTGRESQL
.COM
FORMACIÓN POSTGRESQL
EN ESPAÑOL

MÁS DE 40 CURSOS,
APÚNTATE GRATIS
DURANTE 7 DÍAS

EL NETFLIX
DE POSTGRESQL

PULSA AQUÍ PARA DISFRUTAR TU OFERTA ESPECIAL

También podría gustarte