Documente Academic
Documente Profesional
Documente Cultură
Select y Operaciones
Utilizando SELECT podemos realizar operaciones y obtener los resultados como columna
temporales.
Por ejemplo existe la función CONCAT que permite unir dos o más strings. Entonces podemos
escribir:
Veremos:
concat
-----------
JuanPerez
(1 row)
concat
-----------
Juan Perez
(1 row)
largo_del_nombre
7
Otras operaciones
Otras operaciones frecuentemente utilizadas son:
Por ejemplo podemos utilizar para calcular la edad promedio de nuestro contactos.
Hace poco aprendimos a seleccionar el mayor de los valores combinando las instrucciones de order
by y limit pero también dijimos que había una forma más fácil de hacerlo, y es con la función MAX
max
-----
21
(1 row)
Sin embargo si queremos seleccionar otras columnas en conjunto con el máximo para saber a quien
corresponde obtendremos un error.
MAX, COUNT, MIN y SUM son operaciones que se realizan sobre agrupaciones de datos y para
utilizarlas correctamente todavía nos falta aprender a agrupar.
Distintos
Podemos seleccionar datos distintos, o sea eliminar los repetidos, utilizando la función DISTINCT .
Aviso: Al seleccionar múltiples campos se evaluarán las combinaciones donde todos sean únicos.
Como en nuestros datos todos los usuarios tienen distintos nombres no hay combinaciones repetidas,
por lo tanto se muestran todos los datos.
Agrupaciones
SQL nos permite agrupar datos en base a un criterio, por ejemplo agrupando también podemos
seleccionar todos los usuarios que tienen edades distintas.
La ventaja es que al agrupar podemos aplicar otras funciones, por ejemplo podemos contar.
count
-------
1
1
4
2
3
Para mostrar a que edad está asociado a cada cuenta podemos seleccionar ambas columnas.
edad | count
------+-------
19 | 1
23 | 1
20 | 4
22 | 2
21 | 3
Sin embargo cuando agrupamos datos no podemos seleccionar las columnas sobre los datos
agrupados.
El aprendizaje importante es que si agrupamos tenemos que trabajar con las columnas agrupadas.
Trabajando con múltiples tablas
En algunas situaciones necesitaremos consultar datos cuya información está repartida en mas de una
tabla.
Veamos el siguiente caso donde tenemos una tabla de artículos (posts) y otra de comentarios
(comments). Los posts tendrán un título, contenido y un identificador numérico para asegurarnos de
que sean únicos. Los comentarios tendrán solamente contenido y una referencia el identificador del
artículo para saber a que artículo pertenecen.
INSERT INTO posts (title, content) VALUES ('Artículo 1', 'LOREM IPSUM ET ...
');
INSERT INTO posts (title, content) VALUES ('Artículo 2', 'LOREM IPSUM ET ...
');
id title content
content post_id
comentario 1 1
comentario 2 1
comentario 1 2
¿Cómo podemos obtener todos los comentarios indicando a que artículo pertenecen?
La respuesta utilizando un select pero ahora donde utilizamos el from utilizaremos ambas tablas.
Pero esto no muestra exactamente la información que queremos, porque cada comentario aparece
asociado a ambos artículos y eso es un error. La solución es sencilla tenemos que especificar en la
consulta que cada comentario tiene que estar asociado a su respectivo artículo.
Entonces si nuestra tabla de comentarios hubiese tenido la columna id habríamos tenido que escribir
nuestra consulta de la siguiente forma:
Con lo aprendido podemos reescribir nuestra consulta para mostrar todos los artículos junto con los
comentarios.
Dijimos que los uniones (joins) son mas flexibles pero para demostrarlo vamos a ingresar un datos
mas a la tabla de comentarios sin ningún post asociado.
(3 rows)
Esto sucede por que la unión solo nos devuelve los elementos donde hay una relación a menos que
lo especifiquemos, podemos especificar otros tipos de joins con el modificar LEFT o RIGHT
SELECT * FROM comments LEFT JOIN posts on posts.id = comments.post_id;
comentario no asociado
(4 rows)
Tipos de join
INNER JOIN: Une sólo las columnas comunes entre ambas tablas, inner es implícito
LEFT JOIN: Une todas las columnas de la primera tabla con las columnas en común de la segunda
tabla
FULL OUTER JOIN: Une todas las columnas de ambas las tablas
Integridad referencial
La integridad referencial es un concepto muy importante puesto que nos ayuda a evitar que nuestros
datos se corrompan. ¿Cómo pueden corromperse?
Volvamos a un concepto previo muy importante que son las reglas del negocio. Estas reglas de
negocio no son universales, dependen de las necesidades de distintos proyectos. Por ejemplo si
tenemos una aplicación que consiste en un blog, donde tenemos artículos y comentarios puede hacer
sentido que evitemos que un comentario quede en el aire y que no le pertenezca a ningún artículo.
Imponer este arregla ayudaría a evitar que cuando alguien borre un artículo el comentario quede
flotando o ensuciando la base de datos y completamente inaccesible.
En términos técnicos la integridad referencial nos asegura que la clave externa a la que se hace
referencia es válida.
Podemos implementar esta regla agregando una clave foránea, para hacer esto tenemos que
modificar nuestra tabla pero también es posible agregarla la momento de crearla.
Esto se debe a que el id de los posts no es único y si no es único no hay un artículo único al que
estará asociado el comentario lo que es una violación a la integridad referencial.
Las claves foráneas deben estar asociadas a claves ,primarias, de esta forma nos aseguramos que
los valores sean únicos y no puedan ser nulos.
Table "public.comments"
Column | Type | Modifiers
---------+---------+-----------
content | text |
post_id | integer |
Foreign-key constraints:
"fk_comments_post" FOREIGN KEY (post_id) REFERENCES posts(id)
Aprovechemos la oportunidad de poner a prueba la integridad referencial, para hacer esto vamos a
modificar uno de los comentarios y asignaremos un post_id de un post que no existe.
Y obtendremos un error:
Ese es un error bueno, en el sentido de que evita que programas o usuarios que hagan uso de la
base de datos ingresen valores inválidos.
Estas restricción también evita que se borra un post que tenga comentarios.
Aquí podemos ver otro uso importante del LEFT JOIN, si en su lugar hubiésemos ocupado
simplemente un JOIN el artículo 3 no hubiese sido mostrado pues el inner join (o simplemente join)
solo muestra resultados cuando existen elementos asociados.
Veamos un caso donde podría ser útil, supongamos que necesitamos seleccionar todos los usuarios
de nuestro directorio telefónico que cumplan que su edad sea mayor o igual que el promedio. De esta
forma necesitamos una consulta interna para seleccionar el promedio y otra externa para seleccionar
a los usuarios.
Para resolver el problema el primer paso es identificar la consulta interna, en este caso encontrar la
edad promedio.
Ahora solo necesitamos que las edades de nuestros usuarios sean mayores a este número y eso lo
podemos lograr con un simple WHERE
También podemos utilizar información de distintas tablas, por ejemplo si necesitáramos los
comentarios de los últimos 5 posts. Y aquí claramente hay dos consultas primero necesitamos
obtener los ids de los últimos 5 artículos y luego seleccionar los comentarios cuyo post_id esté entre
estos.
Para seleccionar elementos que estén dentro de una tabla como la que acabamos de obtener
ocuparemos el operador IN