Alice Zhao SQL Pocket Guide A Guide To SQL Usage O'Reilly Media
Alice Zhao SQL Pocket Guide A Guide To SQL Usage O'Reilly Media
SQL
ed
ici
ón
Guía de
bolsillo
Guía de uso de SQL
Alice Zhao
O "REILLY
Guía de bolsillo SQL
Si utiliza SQL en su trabajo diario como analista de datos,
científico de datos o ingeniero de datos, esta popular guía es
la referencia ideal para su trabajo. Encontrará muchos
ejemplos que abordan las complejidades del lenguaje, junto con
aspectos de SQL utilizados en Microsoft SQL Server, MySQL,
Oracle Database, PostgreSQL y SQLite.
En esta edición actualizada, la autora Alice Zhao describe
cómo estos sistemas de gestión de bases de datos implementan
la sintaxis SQL tanto para consultar como para realizar cambios
en una base de datos. Encontrará detalles sobre tipos de
datos y conversiones, sintaxis de expresiones regulares,
funciones de ventana, pivoteo y despivoteo, y mucho más.
• Buscar rápidamente cómo realizar tareas específicas
utilizando SQL
• Aplique los ejemplos de sintaxis del libro a sus propias
consultas.
• Las consultas SQL de actualización funcionan en cinco bases
de datos diferentes
sistemas de gestión
• Nuevo: Conectar Python y Ra una base de datos relacional
• Novedad: Consulta de las preguntas más frecuentes sobre SQL
en la sección "Cómo".
¿Yo?
DATOS US $29. 99
ISBN: 978 -1-49
2-09040-3
.
52999 Twitter: @oreillymedia
facebook.com/oreiIIy
9 8149 9040
CUARTA EDICIÓN
Alice Zhao
Guía de bolsillo SQL
por Alice Zhao
Copyright © 2021 Alice Zhao. Todos los
derechos reservados. Impreso en los Estados
Unidos de América.
Publicado por O'Reilly Media, Inc., 1005 Gravenstein Highway North, Sebastopol,
CA 95472.
Los libros de O'Reilly pueden adquirirse para uso educativo, comercial o
promocional. También están disponibles ediciones en línea de la mayoría de
los títulos (http://oreilly.com). Para más información, póngase en contacto
con nuestro departamento de ventas a empresas e instituciones: 800-998-9938
o [email protected].
Prefacio xi
iii
Herramientas de bases de datos 20
Conectar una herramienta de base de datos a una base de datos22
Otros lenguajes de programación 24
Conectar Python a una base de datos 25
Conectar R a una Base de Datos 31
iv | Índice
La cláusula LIMITE 88
iii
Gestión de transacciones 138
Doble comprobación de cambios antes de un COMMIT 139
Deshacer cambios con ROLLBACK 141
vi | Índice
Redondear y truncar números 197
Convertir datos a un tipo de datos numérico 198
Funciones de cadena 199
Determinar la longitud de una cadena 199
Cambiar el caso de una cadena 200
Recortar caracteres no deseados alrededor de una cadena 201
Concatenar cadenas 203
Buscar texto en una cadena 203
Extraer una parte de una cadena 206
Reemplazar texto en una cadena 207
Borrar texto de una cadena 208
Utilizar expresiones regulares 209
Convertir datos a un tipo de cadena 217
Funciones Datetime 218
Devolver la fecha o la hora actual 218
Sumar o restar un intervalo de fecha u hora 220
Encontrar la diferencia entre dos fechas u horas 221
Extraer una parte de una fecha u hora 226
Determinar el día de la semana de una fecha 228
Redondear una fecha a la unidad de tiempo más próxima 229
Convertir una Cadena en un Tipo de Dato Datetime 230
Funciones nulas 234
Devolver un valor alternativo si hay un valor nulo 235
iii
Conceptos básicos de GROUP BY 242
Agregar filas en un único valor o lista 245
CONJUNTOS ROLLUP, CUBE y GROUPING 247
Funciones de ventana 250
Ordenar las filas de una tabla 252
Devolver el primer valor de cada grupo 255
Devuelve el segundo valor de cada grupo 256
Devolver los dos primeros valores de cada grupo 257
Devuelve el valor de la fila anterior 258
Calcular la media móvil 259
Calcular el total 261
Pivotar y despivotar 263
Descomponer los valores de una columna en varios
Columnas 263
Listar los valores de varias columnas en una sola
Columna 265
viii | Índice
Encontrar las filas que contienen valores duplicados 303
Seleccionar filas con el valor máximo de otra columna 306
Concatenar texto de varios campos en uno solo
Campo 308
Buscar todas las tablas que contienen un nombre de columna específico
311
Actualizar una tabla cuyo ID coincide con el de otra tabla 313
Índice 317
iii
Prefacio
xi
SQL existe desde hace casi cinco décadas y no va a desaparecer
pronto. Es uno de los lenguajes de programación más antiguos
que todavía se utiliza ampliamente hoy en día, y estoy muy
contento de compartir lo último y lo mejor con usted en este
libro.
xii | Prefacio
alfabéticamente. En la cuarta edición he reorganizado las
secciones para agrupar conceptos similares. Sigue habiendo
un
xiii
índice al final de este libro que enumera los conceptos
alfabéticamente.
• Debido al número de analistas de datos y científicos de
datos que ahora utilizan SQL en sus trabajos, he añadido
secciones sobre cómo utilizar SQL con Python y R
(lenguajes de programación de código abierto populares),
así como un curso intensivo de SQL para aquellos que
necesitan un repaso rápido.
I. Conceptos básicos
• Los capítulos 1 a 3 presentan palabras clave, conceptos y
herramientas básicas para escribir código SQL.
• El capítulo 4 desglosa cada cláusula de una consulta SQL.
Prefacio xiii
II. Objetos de base de datos, tipos de datos y funciones
• El capítulo 5 enumera las formas más comunes de crear y
modificar objetos dentro de una base de datos.
• El Capítulo 6 enumera los tipos de datos comunes que se utilizan
en SQL.
• El Capítulo 7 enumera los operadores y funciones más comunes
en SQL.
xiv | Prefacio
CONSEJO
Este elemento significa un consejo o sugerencia.
NOTA
Este elemento significa una nota general.
ADVERTENCIA
Este elemento indica una advertencia o precaución.
Prefacio xv
Si cree que el uso que hace de los ejemplos de código no se ajusta
al uso legítimo o a los permisos mencionados anteriormente, no
dude en ponerse en contacto con nosotros en permis-
[email protected].
Prefacio xvii
Encuéntrenos en Facebook:
http://facebook.com/oreilly. Síganos en Twitter:
http://twitter.com/oreillymedia. Véanos en YouTube:
http://youtube.com/oreillymedia.
Agradecimientos
Gracias a Jonathan Gennick por crear esta guía de bolsillo desde
cero y escribir las tres primeras ediciones, y a Andy Kwan por
confiar en mí para continuar con la publicación.
No podría haber terminado este libro sin la ayuda de mis
editores Amelia Blevins, Jeff Bleiel y Caitlin Ghegan, y de mis
revisores técnicos Alicia Nevels, Joan Wang, Scott Haines y
Thomas Nield. Agradezco sinceramente el tiempo que han
dedicado a leer cada página de este libro. Sus comentarios han
sido inestimables.
A mis padres, gracias por fomentar mi amor por aprender y
crear. A mis hijos Henry y Lily, su entusiasmo por este libro me
alegra el corazón. Por último, a mi marido, Ali, gracias por todas
tus notas sobre este libro, por tus ánimos y por ser mi mayor
admirador.
xviii | Prefacio
Prefacio xix
CAPÍTULO 1
Curso intensivo de
SQL
SQL
SQL es la abreviatura de Structured Query Language (lenguaje de
consulta estructurado). Imagina que tienes una aplicación que
recuerda todos los cumpleaños de tus amigos. SQL es el lenguaje
más popular que utilizarías para hablar con esa aplicación.
Inglés: "Hey app. ¿Cuándo es el cumpleaños de mi m a r i d o ?"
SQL: SELECT * FROM cumpleaños
WHERE persona = 'marido';
Las bases de datos SQL suelen denominarse bases de datos
relacionales porque están formadas por relaciones, que más
1
comúnmente se denominan tablas. Una base de datos está
formada por muchas tablas conectadas entre sí. La Figura 1-1
muestra una imagen de una relación en una base de datos SQL .
NoSQL
NoSQL no es sólo SQL. No se tratará en detalle en este libro, pero
quería señalarlo porque el término ha crecido mucho en
popularidad desde la década de 2010 y es importante entender
que hay formas de almacenar datos más allá de las tablas.
Las bases de datos NoSQL suelen denominarse bases de datos no
relacionales y las hay de todos los tamaños y formas. Sus
principales características son que tienen esquemas dinámicos
(lo que significa que el esquema no tiene que estar bloqueado de
antemano) y p e r m i t e n e l escalado horizontal (lo que
1
significa que los datos pueden extenderse por múltiples
máquinas).
Figura 1-2. Una colección (una variante de una tabla) en MongoDB, una
base de datos NoSQL
Dicho todo esto, este libro se centra en las bases de datos SQL.
Incluso con la introducción de NoSQL, la mayoría de las
empresas siguen almacenando la mayor parte de sus datos en
tablas de bases de datos relacionales.
Este libro cubre los fundamentos de SQL junto con los matices
de cinco populares sistemas de gestión de bases de datos:
Microsoft SQL Server, MySQL, Oracle Database, PostgreSQL y
SQLite.
Algunos son propietarios, es decir, son propiedad de una
empresa y su uso cuesta dinero, y otros son de código abierto, es
decir, s u uso es gratuito para cualquiera. La Tabla 1-1 detalla
las diferencias entre los RDBMS.
NOTA
Avanzando en este libro:
Declaraciones SQL
Las personas que tienen acceso de lectura y escritura a una base
de datos pueden realizar las cuatro operaciones. Pueden crear y
borrar tablas, actualizar datos en tablas y leer datos de tablas. En
otras palabras, tienen todo el poder.
Escriben sentencias SQL, que es código SQL general que puede
escribirse para realizar cualquiera de las operaciones CRUD.
Estas personas suelen tener títulos como administrador de bases
de datos (DBA) o ingeniero de bases de datos.
Consultas SQL
Las personas que tienen acceso de lectura a una base de datos
sólo pueden realizar la operación de lectura, es decir, pueden
consultar los datos de las tablas.
Escriben consultas SQL, que son un tipo más específico de
sentencia SQL. Las consultas se utilizan para buscar y mostrar
datos, lo que también se conoce como "leer" datos. Esta acción se
denomina a veces consulta de tablas. Estas personas suelen tener
títulos como analista de datos o científico de datos.
Las dos secciones siguientes son una guía rápida para escribir
consultas SQL, ya que es el tipo de código SQL más común
q u e verás. Encontrará más detalles sobre la creación y
actualización de tablas en el Capítulo 5.
NOTA
El -- es el comienzo de un comentario en SQL, lo que
significa que el texto después de él es sólo para la
documentación y el código no se ejecutará.
En la mayoría de los casos, las cláusulas SELECT y FROM
son obligatorias y el resto de cláusulas son opcionales. La
excepción es si se está seleccionando una función de base
de datos en particular, entonces sólo se requiere el
SELECT.
1. DESDE
2. DONDE
3. GRUPO POR
4. TENIENDO
5. SELECCIONE
6. ORDENAR POR
Un modelo de datos |
11
Encontrará más información sobre estos términos en "Creación
de tablas" e n l a página 97 del capítulo 5.
Un modelo de datos |
13
CAPÍTULO 2
¿Dónde puedo escribir código
SQL?
Este capítulo cubre tres lugares donde puedes escribir código SQL:
Software RDBMS
Para escribir código SQL, primero hay que descargar un
RDBMS como MySQL, Oracle, PostgreSQL, SQL Server o
SQLite. Los matices de cada RDBMS se destacan en
"Software RDBMS" en la página 14.
Herramientas de bases de datos
Una vez descargado un RDBMS, la forma más básica de
escribir código SQL es a través de una ventana de terminal,
que es una pantalla en blanco y negro de sólo texto. La
mayoría de la gente prefiere utilizar una herramienta de
base de datos, que es una aplicación más fácil de usar que se
conecta a un RDBMS entre bastidores.
Una herramienta de base de datos tendrá una interfaz
gráfica de usuario (GUI), que permite a los usuarios
explorar visualmente las tablas y más editar fácilmente el
código SQL. "Herramientas de base de datos" en la página
20 explica cómo conectar una herramienta de base de datos
a un RDBMS.
Otros lenguajes de programación
SQL puede escribirse en muchos otros lenguajes de
13
programación. Este capítulo se centra en dos de ellos:
Python y R. Son populares lenguajes de programación de
código abierto.
Software RDBMS
Esta sección incluye instrucciones de instalación y fragmentos
breves de código para los cinco RDBMS que se tratan en este
libro.
15
¿Qué es una ventana de terminal?
A menudo me referiré a una ventana de terminal en este
capítulo, porque una vez que haya descargado un RDBMS, es la
forma más básica de interactuar con el RDBMS.
Una ventana de terminal es una aplicación de su ordenador que
suele tener un fondo negro y sólo permite introducir texto. El
nombre de la aplicación varía según el sistema operativo:
CONSEJO
Las siguientes secciones incluyen enlaces para descargar
los instaladores de RDBMS para Windows, macOS y
Linux.
En macOS y Linux, una alternativa a la descarga de un
instalador de es utilizar el gestor de paquetes Homebrew.
Una vez instalado Homebrew, puedes ejecutar comandos
de instalación brew sencillos desde el Terminal para
realizar todas las instalaciones RDBMS.
SQLite
SQLite es gratuito y la instalación más ligera, lo que significa que
no ocupa mucho espacio en tu ordenador y es extremadamente
rápido de configurar. Para Windows y Linux, SQLite Tools
puede descargarse desde la página de descargas de SQLite.
macOS viene con SQLite ya instalado.
Software RDBMS | 15
CONSEJO
La forma más sencilla de empezar a utilizar SQLite es
abrir una ventana termi- nal y escribir sqlite3. Con este
enfoque, sin embargo, todo se hace en la memoria, lo que
significa q u e los cambios no se guardarán una vez que
cierre SQLite.
> sqlite3
Si desea que sus cambios se guarden, debe conectarse a
una base de datos al abrir con la siguiente sintaxis:
> sqlite3 mi_nueva_db.db
1|100
Para mostrar bases de datos, mostrar tablas y salir:
sqlite> .bases de
datos sqlite> .tablas
sqlite> .quit
CONSEJO
Si desea mostrar los nombres de las columnas en la salida, escriba:
sqlite> .headers on
Para ocultarlos de nuevo, teclea:
sqlite> .headers off
+------+ ------+
| id| num |
+------+ ------+
|1 | 100 |
+------+ ------+
1 fila en juego (0.00 seg)
Para mostrar bases de datos, cambiar de base de datos, mostrar tablas
y salir:
mysql> mostrar bases de
datos; mysql> conectar
otra_db; mysql> mostrar
tablas;
mysql> quit
Oracle
Oracle es propietario y funciona en máquinas Windows y Linux
. Oracle Database Express Edition, la edición gratuita, puede
descargarse de la página de descargas de Oracle Database XE.
Software RDBMS | 17
El símbolo del sistema para Oracle tiene este aspecto:
SQL>
Algo de código rápido para probar cosas:
SQL> CREATE TABLE test (id int, num int);
SQL> INSERT INTO test VALUES (1, 100);
SQL> INSERT INTO test VALUES (2, 200);
SQL> SELECT * FROM test WHERE ROWNUM <=1;
ID NUM
---------- ----------
1 100
Para mostrar bases de datos, mostrar todas las tablas (incluidas
las tablas del sistema), mostrar tablas creadas por el usuario y
salir:
SQL> SELECT * FROM nombre_global;
SQL> SELECT table_name FROM all_tables;
SQL> SELECT table_name FROM user_tables;
SQL> quit
PostgreSQL
PostgreSQL es gratuito y se utiliza a menudo junto con otras
tecnologías de código abierto. PostgreSQL puede descargarse
desde la página de descargas de PostgreSQL. En macOS y Linux,
como alternativa, puede realizar la instalación con Homebrew
escribiendo brew install postgresql en el Terminal.
El símbolo del sistema para PostgreSQL tiene este aspecto:
postgres=#
Algo de código rápido para probar cosas:
postgres=# CREATE TABLE test (id int, num int);
postgres=# INSERT INTO test VALUES (1, 100),
(2, 200);
postgres=# SELECT * FROM prueba LIMIT 1;
id | num
----+-----
CONSEJO
Si alguna vez ves postgres-#, significa que has olvidado-
ten un punto y coma al final de una sentencia SQL.
Escriba ; y debería volver a ver postgres=#.
Si alguna vez ves :, significa que has sido cambiado
automáticamente al editor de texto vi, y puedes salir
tecleando q.
Servidor SQL
SQL Server es propietario (propiedad de Microsoft) y funciona
en máquinas Windows y Linux. También puede instalarse a
través de Docker. SQL Server Express, la edición gratuita, puede
descargarse desde la página de descargas de Microsoft SQL
Server.
El símbolo del sistema para SQL Server tiene el siguiente aspecto:
1>
Algo de código rápido para probar cosas:
1> CREAR TABLA test (id int, num int);
2> INSERT INTO test VALUES (1, 100), (2, 200);
3> ir
1> SELECT TOP 1 * FROM prueba;
2> ir
Software RDBMS | 19
id número
---------- ----------
1 100
(1 fila afectada)
Para mostrar bases de datos, cambiar de base de datos, mostrar tablas
y salir:
1> SELECT name FROM master.sys.databases;
2> go
1> USE otra_db;
2> ir
1> SELECT * FROM esquema_informacion.tablas;
2> go
1> salir
NOTA
En SQL Server, el código SQL no se ejecuta hasta que se teclea la tecla
go en una nueva línea.
Herramientas de base de
datos | 21
- Incluido con la instalación de PostgreSQL
Herramientas de base de
datos | 23
la nube, donde la gente utiliza servidores propiedad de
empresas como Amazon, Google o Microsoft.
Herramientas de base de
datos | 25
NOTA
En el caso de SQLite, en lugar de rellenar estos cinco
campos de conexión con la base de datos, deberá
introducir la ruta del archivo de base de datos .db al que
intenta conectarse.
conn = cx_Oracle.connect(dsn='localhost/XE',
user=db_config.usr, password=db_config.pwd)
ADVERTENCIA
Cuando utilice cx_Oracle en Python, elimine el punto y
coma (;) al final de todas las consultas para evitar obtener
un error.
id num
01 100
Con SQLAlchemy:
conn.nombres_tabla()
CONSEJO
No todos los argumentos son obligatorios. Si excluye un
argumento por completo, se utilizará el valor
predeterminado.
Haz esto:
install.packages("rstudioapi")
con <- dbConnect(...,
password=rstudioapi::askForPassword("¿Contraseña?"),
...)
[1] "test"
CONSEJO
Para SQL Server, incluya el nombre del esquema para
limitar el número de tablas mostradas-dbListTables(con,
schema="dbo"). dbo significa propietario de la base de
datos y es el esquema por defecto en SQL Server.
id num
1 1 100
2 2 200
NOTA
En Oracle, el nombre de la tabla distingue entre
mayúsculas y minúsculas. Dado que Oracle convierte
automáticamente los nombres de tabla a mayúsculas, es
probable que tenga que ejecutar lo siguiente en su lugar:
dbRead Table(con, "TEST").
id num
1 2 200
[1] "data.frame"
Cierre la conexión cuando haya terminado de utilizar la base de datos.
dbDisconnect(con)
Siempre es una buena práctica cerrar la conexión a la base de datos
para ahorrar recursos.
37
recorre una lista, elemento por elemento, y añade cada valor a
un total para calcular finalmente la suma total:
calorías = [90, 240, 165]
total = 0
para c en calorías:
total += c
print(total)
Con SQL, en lugar de decirle a un ordenador exactamente
c ó m o quieres hacer algo, te limitas a describir lo que
quieres que haga, que en este caso es calcular la suma. Entre
bastidores, SQL calcula cómo ejecutar el código de forma
óptima. Esto se llama declarative programming.
SELECT SUMA(calorías)
DE los entrenamientos;
Lo más importante es que SQL no es un lenguaje de
programación de uso general como Python, Java o C++, que
pueden utilizarse para una gran variedad de aplicaciones. Por el
contrario, SQL es un lenguaje de programación especial, creado
específicamente para gestionar datos en una base de datos
relacional.
Normas ANSI | 39
¿Debo seguir las normas?
La mayor parte del código SQL básico que escribes se adhiere a
las normas ANSI ards. Si encuentra código que hace algo
complejo utilizando palabras clave sencillas pero desconocidas,
es muy probable que esté fuera de los estándares.
Si trabaja únicamente con un RDBMS, como Oracle o SQL
Server, no hay ningún problema en no seguir las normas ANSI y
aprovechar todas las funciones del software.
El problema surge cuando se tiene código funcionando en un
RDBMS que se quiere utilizar en otro RDBMS. Es probable
q u e e l código que no sea ANSI no funcione en el nuevo
RDBMS y haya que reescribirlo.
-- ANSI-92
SELECT c.id, c.name, o.date
FROM cliente c INNER JOIN pedido
o ON c.id = o.id;
Términos SQL
Este es un bloque de código SQL que muestra el número de
ventas que cada empleado cerró en 2021. Utilizaremos este
bloque de código para resaltar una serie de términos SQL.
-- Ventas cerradas en 2021
SELECT e.name, COUNT(s.sale_id) AS num_sales
FROM empleado e
LEFT JOIN ventas s ON e.emp_id =
s.emp_id WHERE YEAR(s.fecha_venta) = 2021
AND s.closed IS NOT NULL
GROUP BY e.name;
Términos SQL | 41
Palabras clave y funciones
Las palabras clave y las funciones son términos integrados en SQL.
Palabras clave
Una palabra clave es un texto que ya tiene algún significado en
SQL. Todas las palabras clave en el bloque de código están en
negrita aquí:
SELECT e.name, COUNT(s.sale_id) AS num_sales
FROM empleado e
LEFT JOIN ventas s ON e.emp_id = s.emp_id
WHERE AÑO(s.fecha_venta) = 2021
AND s.closed IS NOT NULL
GROUP BY e.name;
Funciones
Una función es un tipo especial de palabra clave. Toma cero o
más entradas, hace algo con las entradas y devuelve una salida.
En SQL, una función suele ir seguida de paréntesis, pero no
siempre. Las dos funciones en el bloque de código están en
negrita aquí:
SELECT e.name, COUNT(s.sale_id) AS num_sales
FROM empleado e
LEFT JOIN ventas s ON e.emp_id = s.emp_id
WHERE YEAR(s.fecha_venta) = 2021
AND s.closed IS NOT NULL
GROUP BY e.name;
Identificadores y alias
Los identificadores y alias son términos que define el usuario.
Identificadores
Un identificador es el nombre de un objeto de la base de datos,
como una tabla o una columna. Todos los identificadores del
bloque de código aparecen en negrita:
SELECT e.name, COUNT(s.sale_id) AS num_sales
FROM empleado e
LEFT JOIN ventas s ON e.emp_id =
s.emp_id WHERE YEAR(s.fecha_venta) = 2021
AND s.closed IS NOT NULL
GROUP BY e.name;
Los identificadores deben empezar por una letra (a-z o A-Z),
seguida de cualquier combinación de letras, números y guiones
bajos (_). Algunos programas permiten caracteres adicionales
como @, # y $.
Para facilitar la lectura, los identificadores suelen ir en
minúsculas, mientras que las palabras clave van en mayúsculas,
aunque el código se ejecutará con independencia de mayúsculas
y minúsculas.
Términos SQL | 43
CONSEJO
Como práctica recomendada, los identificadores no deben
tener el mismo nombre que una palabra clave existente.
Por ejemplo, no q u e r r á s nombrar una columna
COUNT porque ya es una palabra clave en SQL.
Si aún así decide hacerlo, puede evitar confusiones
encerrando el identificador entre comillas dobles en . Así,
en lugar de llamar a una columna CONTAR, puede llamarla
"CONTAR", pero es mejor utilizar un nombre
completamente distinto, como num_ventas.
MySQL utiliza puntos suspensivos (``) para encerrar
identificadores en lugar de comillas dobles ("").
Alias
Un alias cambia el nombre de una columna o una tabla
temporalmente, sólo durante el tiempo que dure la consulta en .
En otras palabras, los nuevos nombres de alias aparecerán en los
resultados de la consulta, pero los nombres originales de las
columnas permanecerán inalterados en las tablas desde las que
se realiza la consulta. Todos los alias del bloque de código
aparecen en negrita:
SELECT e.name, COUNT(s.sale_id) AS num_sales
FROM empleado e
LEFT JOIN ventas s ON e.emp_id =
s.emp_id WHERE YEAR(s.fecha_venta) = 2021
AND s.closed IS NOT NULL
GROUP BY e.name;
La norma es utilizar AS cuando se renombran columnas (AS
num_ventas) y ningún texto adicional cuando se renombran
tablas (e). Sin embargo, técnicamente, cualquiera de las dos
sintaxis sirve tanto para columnas como para tablas.
Además de las columnas y tablas, los alias también son útiles si
desea asignar un nombre temporal a una subconsulta.
Declaraciones
Una sentencia comienza con una palabra clave y termina con un
punto y coma. Todo este bloque de código se denomina
sentencia SELECT porque empieza por la palabra clave SELECT.
CONSEJO
Muchas herramientas de bases de datos que proporcionan
una interfaz gráfica de usuario no requieren el punto y
coma (;) al final de una sentencia.
Cláusulas
Una cláusula es una forma de referirse a una sección concreta de
una sentencia. Esta es nuestra sentencia SELECT original:
SELECT e.name, COUNT(s.sale_id) AS num_sales
FROM empleado e
LEFT JOIN ventas s ON e.emp_id =
s.emp_id WHERE YEAR(s.fecha_venta) = 2021
AND s.closed IS NOT NULL
GROUP BY e.name;
Términos SQL | 45
Esta declaración contiene cuatro cláusulas principales:
• Cláusula SELECT
SELECT e.name, COUNT(s.sale_id) AS num_sales
• Cláusula FROM
FROM empleado e
LEFT JOIN ventas s ON e.emp_id = s.emp_id
• Cláusula WHERE
WHERE YEAR(s.fecha_venta) =
2021 AND s.cerrado IS NOT
NULL
• Cláusula GROUP BY
GROUP BY e.name;
NOTA
En realidad, esta frase tiene más cláusulas que las cuatro
e n u m e r a d a s . En gramática, una cláusula es una
parte de una frase que contiene un sujeto y un verbo. Así
que podrías referirte a lo siguiente:
LEFT JOIN ventas s ON e.emp_id = s.emp_id
como la cláusula LEFT JOIN si desea especificar aún más
la sección del código a la que se refiere.
Expresiones
Una expresión puede considerarse como una fórmula que da
como resultado un valor . Una expresión en el bloque de código
era:
COUNT(s.venta_id)
Esta expresión incluye una función (COUNT) y un identificador
(s.sale_id). Juntos, forman una expresión que dice contar el
número de ventas.
Otros ejemplos de expresiones son:
Predicados
Un predicado es una comparación lógica que da como resultado
uno de estos tres valores VERDADERO/FALSO/DESCONOCIDO. A veces
se denominan sentencias condicionales. Los tres predicados del
bloque de código están en negrita:
SELECT e.name, COUNT(s.sale_id) AS num_sales
FROM empleado e
LEFT JOIN ventas s ON e.emp_id = s.emp_id
WHERE AÑO(s.fecha_venta) = 2021
AND s.closed IS NOT NULL
GROUP BY e.name;
Algunas cosas que notarás en estos ejemplos son:
Términos SQL | 47
• NULL significa sin valor. Cuando se comprueba si un campo
no tiene valor, en lugar de escribir = NULL, se escribiría IS
NULL.
Comentarios
Un comentario es un texto que se ignora cuando se ejecuta el
código, como el siguiente .
-- Ventas cerradas en 2021
Es útil incluir comentarios en tu código para que otros revisores
del mismo (¡incluido tu futuro yo!) puedan entender
rápidamente la intención del código sin leerlo todo.
Para comentar:
/* Estos son
mis
comentarios */
Citas
Hay dos tipos de comillas que se pueden utilizar en SQL, la
comilla simple y la comilla doble.
SELECT "Esta columna"
FROM mi_tabla
WHERE nombre = 'Bob';
NOTA
MySQL utiliza puntos suspensivos (``) para encerrar
identificadores en lugar de comillas dobles ("").
Espacio en blanco
A SQL no le importa el número de espacios entre términos. Ya
sea un espacio, un tabulador o una nueva línea, SQL ejecutará la
consulta desde la primera palabra clave hasta el punto y coma al
final de la sentencia. Las dos consultas siguientes son
equivalentes.
SELECT * FROM mi_tabla;
SELECT *
FROM mi_tabla;
Términos SQL | 49
NOTA
En el caso de consultas SQL sencillas, es posible que veas
todo el código escrito en una sola línea. En el caso de
consultas más largas, con docenas o incluso cientos de
líneas, verás nuevas líneas para nuevas cláusulas, pestañas
al enumerar muchas columnas o tablas, etc.
El objetivo final es tener un código legible, por lo que
tendrás que decidir cómo quieres espaciar el código (o
seguir las directrices de tu empresa) para que tenga un
aspecto limpio y s e p u e d a hojear rápidamente.
Sublenguas
Existen muchos tipos de sentencias que pueden escribirse en
SQL. Todos ellos caen bajo uno de los cinco sublenguajes, que se
detallan en la Tabla 3-1.
Tabla 3-1. Sublenguajes SQL
Sublengua Descripción Común
Comando
s de referencia Secciones
Lenguaje de Este es el lenguaje con el SELECT La mayor parte
consulta de que la mayoría de la de este libro
datos (DQL) gente está familiarizada . está dedicada
Estas sentencias se a DQL
utilizan para recuperar
información de un objeto
de base de datos, como
una tabla, y suelen
denominarse consultas
SQL.
Lenguaje de manipulación de Es el crear un objeto de base de
definición de datos (DML) lenguaj datos, como una tabla o un
e índice.
datos (DDL)
utilizad Es el lenguaje utilizado
o para para manipular o modificar
definir o los datos de una base de
Lenguaje de
50 | Capítulo 3: El lenguaje SQL
datos. CREAR ALTERAR C lizar y borrar
SOLTAR r
e
INSERTAR
a
r
ACTUALIZAR
,
SUPRIMIR
a
c
t
u
a
l
i
z
a
r
b
o
r
r
a
r
C
r
e
a
r
,
a
c
t
u
a
Términos SQL | 51
Sublengua Descripción Común
Comando
s de referencia Secciones
Lenguaje de Es el lenguaje utilizado REVOCACI No cubierto
control de para controlar el acceso a ÓN DE
datos (DCL) los datos de una base de LA
datos, lo que a veces se SUBVENCI
denomina permisos o ÓN
privilegios. Gestión de
Lenguaje de Es el lenguaje utilizado transacciones
control de para gestionar
transacciones transacciones en una COMETER
( TCL) base de datos, o aplicar RETROCES
cambios permanentes a O
una base de datos.
Sublenguas | 51
CAPÍTULO 4
Conceptos básicos
de consulta
1. SELECCIONE
2. DESDE
3. DONDE
4. GRUPO POR
5. TENIENDO
6. ORDENAR POR
53
condado
comarcas donde se encuentran las cascadas
visi
ta recorridos con múltiples paradas en cascadas
tour_name numero_cascadas
---------- ---------------
M-28 6
Munising 6
US-2 4
Consultar una base de datos significa obtener datos de una base
de datos, normalmente de una tabla o varias tablas.
NOTA
También es posible consultar una vista en lugar de una
tabla. Las vistas se parecen a las tablas y derivan de ellas,
pero no contienen datos. Encontrará más información
sobre las vistas en "Vistas", en la página 133 del Capítulo
5.
Selección de columnas
La cláusula SELECT más sencilla enumera uno o más nombres de
columnas de las tablas de la cláusula FROM:
SELECT id, nombre
DEL propietario;
identificador nombre
----- ----------------
1 Rocas Pictured
2 Naturaleza de Michigan
3 AF LLC
4 MI DNR
5 Cataratas Horseshoe
La cláusula SELECT | 55
ADVERTENCIA
El asterisco es un atajo útil cuando se prueban consultas,
ya que puede ahorrarle bastante tiempo de escritura. Sin
embargo, es arriesgado utilizar el asterisco en código de
producción porque las columnas de una tabla pueden
cambiar con el tiempo, haciendo que tu código falle
cuando haya menos o más columnas de las esperadas.
Selección de expresiones
Además de enumerar simplemente las columnas, también puede
enumerar expresiones más complejas dentro de la cláusula
SELECT para que aparezcan como columnas en los resultados.
El siguiente enunciado incluye una expresión para calcular un
descenso del 10% de la población, redondeado a cero decimales:
SELECT nombre, ROUND(población * 0,9, 0)
DESDE el condado;
Selección de funciones
Las expresiones de la lista SELECT suelen hacer referencia a
columnas de las tablas de las que se está extrayendo información,
pero hay excepciones. Por ejemplo, una función común que no
hace referencia a ninguna tabla es la que devuelve la fecha actual:
SELECT FECHA_ACTUAL;
FECHA_ACTUAL
-------------
2021-12-01
NOTA
La mayoría de las consultas incluyen una cláusula SELECT
y una cláusula FROM, pero sólo es necesaria la cláusula
SELECT cuando se utilizan funciones concretas de la base
de datos, como CURRENT_DATE.
Aliasing Columns
El propósito de un alias de columna es dar un nombre temporal
a cualquier columna o expresión listada en la cláusula SELECT.
Ese nombre temporal, o alias de columna, se muestra como
nombre de columna en los resultados.
Tenga en cuenta que no se trata de un cambio de nombre
permanente, ya que los nombres de las columnas de las tablas
originales no cambian. El alias sólo existe dentro de la consulta.
Este código muestra tres columnas.
SELECCIONE id, nombre,
ROUND(población * 0,9, 0)
DESDE el condado;
La cláusula SELECT | 57
Supongamos que queremos renombrar los nombres de las
columnas de los resultados. id es demasiado ambiguo y nos
gustaría darle un nombre más descriptivo. ROUND(population *
0.9, 0) es demasiado largo y nos gustaría darle un nombre más
sencillo.
Para crear un alias de columna, a continuación del nombre o la
expresión de una columna, debe aparecer (1) un nombre de alias
o (2) la palabra clave AS y un nombre de alias.
-- alias_name
SELECT id county_id, nombre,
ROUND(población * 0,9, 0) población_estimada
DESDE el condado;
o:
-- AS alias_name
SELECT id AS county_id, name,
ROUND(población * 0,90, 0) AS población_estimada
DESDE el condado;
NOTA
Las versiones antiguas de PostgreSQL requieren el uso de
AS al crear un alias de columna.
Columnas de calificación
Supongamos que escribes una consulta que extrae datos de dos
tablas y ambas contienen una columna llamada nombre. Si sólo
incluyeras nombre en la cláusula SELECT, el código no sabría a qué
tabla te estás refiriendo.
Para resolver este problema, puede calificar un nombre de
columna por su nombre de tabla . En otras palabras, puedes dar
a una columna un prefijo para especificar a qué tabla pertenece
utilizando la notación por puntos, como en
nombre_tabla.nombre_columna.
El siguiente ejemplo consulta una única tabla, por lo que, aunque
no es necesario calificar las columnas, se muestra a modo de
demostración. Así es como se califica una columna por su
nombre de tabla:
La cláusula SELECT | 59
SELECT propietario.id, propietario.nombre
DEL propietario;
CONSEJO
Si se produce un error en SQL al hacer referencia a un
nombre de c o l u m n a ambiguo, significa que varias
tablas de la consulta tienen una columna con el mismo
nombre y que no se ha especificado en a qué combinación
de tabla y columna se hace referencia. Puede resolver el
error calificando el nombre de la columna.
Tablas de clasificación
Si califica un nombre de columna por su nombre de tabla,
también puede calificar ese nombre de tabla por su nombre de
base de datos o esquema. La siguiente consulta recupera datos
específicamente de la tabla owner dentro del esquema sqlbook:
SELECT sqlbook.owner.id, sqlbook.owner.name
FROM sqlbook.owner;
El código anterior es largo ya que sqlbook.owner se repite varias
veces. Para ahorrar tiempo, puede proporcionar un alias de
tabla. El siguiente ejemplo da el alias o a la tabla owner:
SELECT o.id, o.name
FROM sqlbook.owner o;
o:
SELECT o.id, o.name
FROM propietario o;
Selección de subconsultas
Una subconsulta es una consulta anidada dentro de otra
consulta. Las subconsultas pueden ubicarse dentro de varias
cláusulas, incluida la cláusula SELECT de .
En el siguiente ejemplo, además del id, el nombre y la población,
digamos que también queremos ver la población media de todos
los condados. Al incluir una subconsulta, estamos creando una
nueva columna en los resultados para la población media.
SELECT id, nombre, población,
(SELECT AVG(población) FROM condado)
AS average_pop
DESDE el condado;
id nombrepoblación población_media
----- ---------- ----------- ------------
2 Alger 9862 18298
6 Baraga 8746 18298
7 Ontonagon 7818 18298
...
Hay que tener en cuenta algunas cosas:
La cláusula SELECT | 61
que en este caso era average_pop. De esta forma, la columna
tiene un nombre sencillo en los resultados.
• Sólo hay un valor en la columna población_media que se
repite en todas las filas. Cuando se incluye una subconsulta
dentro de la cláusula SELECT, el resultado de la subconsulta
debe devolver una única columna y cero o una fila, como se
muestra en la siguiente subconsulta para calcular la
población media.
AVG(población)
----------------
18298
La cláusula SELECT | 63
SELECT o.id, o.name,
(SELECT COUNT(*) FROM cascada w
WHERE o.id = w.owner_id) AS num_waterfalls
DEL propietario o;
DISTINTO
Cuando se enumera una columna en la cláusula SELECT, por
defecto se devuelven todas las filas. Para ser más explícito, puede
incluir la palabra clave ALL, pero es puramente opcional. Las
siguientes consultas devuelven cada combinación
tipo/open_to_public.
tipo open_to_public
-------- ---------------
público y
público y
público y
privado y
privado y
privado y
privado y
público y
Si desea eliminar filas duplicadas de los resultados, puede utilizar
la palabra clave DISTINCT. La siguiente consulta devuelve una
lista de combinaciones únicas de tipo/open_to_public.
SELECT DISTINCT o.type, w.open_to_public
FROM owner o
JOIN cascada w ON o.id = w.owner_id;
tipo open_to_public
-------- ---------------
public y
privado y
COUNT y DISTINCT
Para contar el número de valores únicos dentro de una única
columna, puede combinar las palabras clave COUNT y DISTINCT
dentro de la cláusula SELECT de . La siguiente consulta devuelve
el número de valores únicos de tipo.
La cláusula SELECT | 65
SELECT COUNT(DISTINCT type) AS unique
FROM owner;
único
-------
2
Para contar el número de combinaciones únicas de varias
columnas, puede envolver una consulta DISTINCT como una
subconsulta y, a continuación, realizar un COUNT en la
subconsulta. La siguiente consulta devuelve el número de
combinaciones únicas de tipo/open_to_public.
SELECT COUNT(*) AS num_unique
FROM (SELECT DISTINCT o.type, w.open_to_public
FROM owner o JOIN waterfall w
ON o.id = w.owner_id) my_subquery;
num_único
-----------
2
MySQL y PostgreSQL admiten el uso de la sintaxis
COUNT(DISTINCT) en varias columnas. Las dos consultas
siguientes son equivalentes a la consulta anterior, sin necesidad
de una subconsulta:
-- Equivalente de MySQL
SELECT COUNT(DISTINCT o.type, w.open_to_public)
AS num_unique
FROM propietario o JOIN
cascada w ON o.id =
w.owner_id;
-- Equivalente de PostgreSQL
SELECT COUNT(DISTINCT (o.type, w.open_to_public))
AS num_unique
FROM propietario o JOIN
cascada w ON o.id =
w.owner_id;
num_único
-----------
La cláusula SELECT | 67
La cláusula FROM
La cláusula FROM se utiliza para especificar la fuente de los datos
que desea recuperar . El caso más sencillo es nombrar una única
tabla o vista en la cláusula FROM de la consulta.
SELECT nombre
FROM cascada;
Puede calificar una tabla o una vista con un nombre de base de
datos o de esquema utilizando la notación de puntos. La
siguiente consulta recupera datos específicamente de la tabla
waterfall dentro del esquema sqlbook:
SELECCIONAR nombre
FROM sqlbook.waterfall;
NOTA
Es posible que vea las cláusulas FROM, JOIN y ON en líneas
diferentes o con sangría. Esto no es necesario, pero resulta
útil para facilitar la lectura, especialmente cuando se
u n e n varias tablas.
Tabla de resultados
Una consulta siempre da como resultado una única tabla. La
tabla cascada tiene 12 columnas y la tabla recorrido tiene 3
columnas. Tras unir estas tablas, la tabla de resultados tiene 15
columnas.
La cláusula FROM | 67
id nombre ... nombre para...
----- --------------- --------- -----
1 Cataratas M-28 1
Munising
1 Cataratas Munising 1
Munising
2 Cascadas Munising 2
Tannery
3 Cataratas de M-28 3
Alger
3 Cataratas de Munising 3
Alger
...
Observará que hay dos columnas llamadas nombre en la tabla de
resultados. La primera es de la tabla cascada y la segunda es de
la tabla recorrido. Para referirse a ellas en la cláusula SELECT ,
tendría que calificar los nombres de las columnas.
SELECCIONE w.nombre, t.nombre
FROM cascada w JOIN gira t
ON w.id = t.parada;
nombre nombre
--------------- ---------
Munising Falls M-28
Munising Falls Munising
Tannery Falls Munising
...
Para diferenciar las dos columnas, también puede utilizar el alias
para los nombres de las columnas.
SELECT w.name AS waterfall_name,
t.name AS tour_name
FROM cascada w JOIN gira t
ON w.id = t.parada;
nombre_cascada nombre_viaje
--------------- ----------
Munising Falls M-28
Munising Falls Munising
Tannery
FallsMun
La cláusula FROM | 69
variaciones JOIN
En el ejemplo anterior, si una cascada no aparece en ningún
recorrido, no aparecerá en la tabla de resultados. Si quisiera ver
todas las cascadas en los resultados, tendría que utilizar o t r o
tipo de unión.
A partir de subconsultas
Una subconsulta es una consulta anidada dentro de otra
consulta. Las subconsultas dentro de la cláusula FROM deben ser
sentencias SELECT independientes, lo que significa que no hacen
referencia a la consulta externa en absoluto y pueden ejecutarse
por sí solas.
NOTA
Una subconsulta dentro de la cláusula FROM también se
conoce como tabla derivada porque la subconsulta acaba
actuando esencialmente como una tabla mientras dura la
consulta.
cascada_nombre propietario_nombre
--------------- ---------------
Little Miners Pictured Rocks
Miners Falls Pictured Rocks
Munising Falls Pictured Rocks
Wagner Falls MI DNR
Es importante comprender el orden en que se ejecuta la consulta.
NOTA
Los alias son necesarios para las subconsultas dentro de la
cláusula FROM en MySQL, PostgreSQL y SQL Server, pero
no en Oracle y SQLite.
La cláusula FROM | 71
Paso 2: Ejecutar la consulta completa
A continuación, puede pensar en la letra o ocupando el lugar de
la s u b c o n s u l t a . La consulta se ejecuta ahora como
de costumbre.
SELECT w.name AS waterfall_name,
o.name AS owner_name
FROM o JOIN cascada w
ON o.id = w.owner_id;
cascada_nombre propietario_nombre
--------------- ---------------
Little Miners Pictured Rocks
Miners Falls Pictured Rocks
Munising Falls Pictured Rocks
Wagner Falls MI DNR
nombre número_paradas
--------- ---------
- M-28 11
Munising 6
US-2 14
AVG(número_paradas)
-----------------
10.3333333333333
La cláusula FROM | 73
JOIN waterfall w ON o.id = w.owner_id
WHERE o.type = 'public';
cascada_nombre propietario_nombre
--------------- ---------------
Little Miners Pictured Rocks
Miners Falls Pictured Rocks
Munising Falls Pictured Rocks
Wagner Falls MI DNR
La cláusula WHERE
La cláusula WHERE se utiliza para restringir los resultados de la
consulta a sólo las filas de interés de , o dicho de otro modo, es el
lugar donde filtrar los datos. Rara vez q u e r r á mostrar todas
las filas de una tabla, sino más bien las filas que coincidan con
criterios específicos.
La cláusula WHERE | 73
CONSEJO
Al explorar una tabla con millones de filas, nunca querrás
hacer un SELECT * FROM mi_tabla; porque tardará un
tiempo innecesariamente largo en ejecutarse.
En su lugar, conviene filtrar los datos. Dos formas
comunes de hacerlo son:
Filtrar por una columna dentro de la cláusula WHERE
Mejor aún, filtre por una columna que ya esté
indexada para que la recuperación sea aún más
rápida.
SELECCIONAR *
FROM mi_tabla
WHERE year_id = 2021;
Mostrar las primeras filas de datos con la cláusula LIMIT
(o WHERE ROWNUM <= 10 en Oracle o SELECT TOP 10 * en
SQL Server)
SELECCIONAR *
FROM mi_tabla
LÍMITE 10;
identificador nombre
----- ----------------
7 pequeños mineros
14 Rapid River Fls
Predicados múltiples
También es posible combinar varios predicados con operadores
como AND u OR. El siguiente ejemplo muestra cascadas sin Falls
en su nombre y que tampoco tienen propietario:
SELECT id, name
FROM cascada
WHERE name NOT LIKE '%Falls%'
AND owner_id IS NULL;
identificador nombre
----- ----------------
14 Rapid River Fls
Encontrará más información sobre los operadores en
Operadores, en el C a p í t u l o 7.
Filtrado de subconsultas
Una subconsulta es una consulta anidada dentro de otra, y la
cláusula WHERE de es un lugar habitual para encontrar una. El
siguiente ejemplo recupera las cascadas de acceso público
situadas en el condado de Alger:
SELECCIONE w.nombre
DESDE cascada w
WHERE w.open_to_public = 'y'
AND w.county_id IN (
SELECT c.id FROM condado c
WHERE c.name = 'Alger');
La cláusula WHERE | 75
nombre
---------------
Cascadas Munising
Cascadas
Tannery
Cascadas Alger
...
NOTA
A diferencia de las subconsultas dentro de la cláusula
SELECT o la cláusula FROM, las subconsultas en la cláusula
WHERE no requieren un alias. De hecho, recibirá un error
si incluye un alias.
La cláusula WHERE | 77
SELECT c.id FROM condado c
WHERE c.name = 'Alger');
o:
-- Cláusula JOIN
SELECT w.name
FROM waterfall w INNER JOIN county c
ON w.county_id = c.id
WHERE w.open_to_public = 'y'
AND c.name = 'Alger';
nombre
---------------
Cascadas Munising
Cascadas
Tannery
Cascadas Alger
...
Las dos consultas producen los mismos resultados. La ventaja
del primer enfoque es que las subconsultas suelen ser más fáciles
de entender que las uniones. La ventaja del segundo enfoque es
que las uniones suelen ejecutarse más rápido que las
subconsultas.
Cláusula GROUP BY
El propósito de la cláusula GROUP BY es reunir las filas en grupos
y resumir las filas dentro de los grupos de alguna manera ,
devolviendo finalmente sólo una fila por grupo. En ocasiones,
esto se denomina "dividir" las filas en grupos y "agrupar" las filas
de cada grupo.
La siguiente consulta cuenta el número de cascadas a lo largo de
cada uno de los recorridos:
SELECTt .name COMO tour_name,
COUNT(*) AS num_waterfalls
FROM cascada w INNER JOIN gira t
ON w.id = t.parada
GROUP BY t.name;
tour_name numero_cascadas
La cláusula WHERE | 79
---------- ---------------
M-28 6
Munising 6
US-2 4
Hay dos partes en las que centrarse aquí:
MunisingCascada
s
MunisingCascada
s Tannery
MunisingCascada
s Alger
MunisingCascada
s Wagner MunisingCascadas
Horseshoe
MunisingCascada
La cláusula GROUP BY | 79
s Miners
ADVERTENCIA
En este ejemplo, COUNT(*) devuelve el número de cascadas
de cada recorrido. Sin embargo, esto se debe únicamente
a que cada fila de datos de las tablas de cascadas y
recorridos representa una única cascada.
Si una misma cascada apareciera en varias filas, COUNT(*)
daría como resultado un valor mayor del esperado. En este
caso, podría utilizar COUNT(DISTINCT nombre_cascada)
para encontrar las cascadas únicas. Encontrará más
información en en COUNT y DISTINCT.
La clave es que es importante volver a comprobar
manualmente los resultados de la función de agregación
para asegurarse de que resume los datos de la forma
prevista.
La cláusula GROUP BY | 81
Ahora que se han creado los grupos con la cláusula GROUP BY, la
función de agregado se aplicará una vez a cada grupo:
tour_name COUNT(*)
---------- ---------
M-28 6
M-28
M-28
M-28
M-28
M-28
Munising 6
Munising
Munising
Munising
Munising
Munising
US-2 4
US-2
US-2
US-2
GROUP BY En la práctica
Estos son los pasos que debe seguir cuando utilice un GROUP BY:
1. Averigüe qué columna o columnas desea utilizar para
s e p a r a r o agrupar los datos (por ejemplo, el nombre
del circuito).
2. Calcula cómo te gustaría resumir los datos dentro de cada
grupo (por ejemplo, contar las cascadas dentro de cada
recorrido).
Cuando te hayas decidido por ellos:
1. En la cláusula SELECT, enumere la columna o columnas
por las que desea agrupar (por ejemplo, nombre del
recorrido) y la agregación o agregaciones que desea
calcular dentro de cada grupo (por ejemplo, recuento de
cascadas).
2. En la cláusula GROUP BY, enumere todas las columnas que
no sean agregaciones (es decir, nombre del recorrido).
La cláusula GROUP BY | 83
página 242 en el Capítulo 8.
NOTA
Una cláusula HAVING siempre sigue inmediatamente a una
cláusula GROUP BY . Sin una cláusula GROUP BY, no puede
haber cláusula HAVING.
tour_name numero_cascadas
---------- ---------------
M-28 6
Munising 6
US-2 4
Supongamos que sólo queremos listar los circuitos que tienen
exactamente seis paradas. Para ello, añada una cláusula HAVING
después de la cláusula GROUP BY:
SELECTt .name COMO tour_name,
COUNT(*) AS num_waterfalls
FROMwaterfall w INNER JOIN
tour t
ON w.id = t.stop
GROUP BY t.name
HAVINGCOUNT (*) = 6;
La cláusula HAVING | 83
tour_name numero_cascadas
---------- ---------------
M-28 6
Munising 6
NOTA
MySQL y SQLite son excepciones, y permiten los alias
(num_waterfalls) en la cláusula HAVING.
La cláusula ORDER BY
La cláusula ORDER BY se utiliza para especificar cómo desea que
se ordenen los resultados de una consulta.
La siguiente consulta devuelve una lista de propietarios y
cascadas, sin ordenar:
SELECT COALESCE(o.name, 'Desconocido') AS
owner, w.name AS waterfall_name
DESDE cascada w
LEFT JOIN owner o ON w.owner_id = o.id;
propietario nombre_cascada
---------------- ---------------
Pictured Rocks MunisingFalls
Michigan NatureTannery Falls AF
LLC Alger Falls
MI DNRWagner Falls
DesconocidoHorseshoe Falls
...
La cláusula ORDER BY | 85
La función COALESCE
La función COALESCE sustituye todos los valores NULL de una
columna por un valor diferente. En este caso, convirtió los
valores NULL de la columna o.name en el texto Desconocido.
Si no se hubiera utilizado aquí la función COALESCE, todas las
cascadas sin propietario habrían quedado fuera de los
resultados. En cambio, ahora se marcan como de propietario
Desconocido, y se pueden clasificar e incluir en los resultados.
Encontrará más detalles en el capítulo 7.
propietario nombre_cascada
---------------- ---------------
AF LLCAlger Falls
MI DNR
FallsNaturale
za de Michigan Tannery Falls
Naturaleza de Michigan Twin
Falls nº 1 Naturaleza de
Michigan Twin Falls nº 2
...
La ordenación por defecto e s ascendente, lo que significa que el
texto irá de la A a la Z y los números irán de menor a mayor.
Puede utilizar las palabras clave ASCENDING y DESCENDING (que
pueden abreviarse como ASC y DESC) para controlar la
ordenación en cada columna de .
propietario nombre_cascada
---------------- ---------------
DesconocidoAgate Falls
DesconocidoBond Falls
DesconocidoCanyon Falls
...
Puede ordenar por columnas y expresiones que no estén en su
Lista SELECT:
SELECTCOALESCE (o.name, 'Desconocido') COMO
owner, w.name COMO waterfall_name
DESDE cascada w
LEFT JOIN owner o ON w.owner_id = o.id
ORDER BY o.id DESC, w.id;
propietario nombre_cascada
---------------- ---------------
MI DNRWagner Falls
AF LLC Alger Falls
MichiganNaturaleza Tannery
Falls
...
También puede ordenar por posición numérica de columna:
SELECT COALESCE(o.name, 'Desconocido') AS
owner, w.name AS waterfall_name
...
ORDENADO POR 1 DESC, 2 ASC;
propietario nombre_cascada
---------------- ---------------
DesconocidoAgate Falls
DesconocidoBond Falls
La cláusula ORDER BY | 87
DesconocidoCanyon Falls
...
Dado que las filas de una tabla SQL no están ordenadas, si no
incluye una cláusula ORDER BY en una consulta, cada vez que
ejecute la consulta, los resultados podrían mostrarse en un orden
diferente.
La cláusula LIMITE
Cuando se visualiza rápidamente una tabla, es una buena
práctica devolver un número limitado de filas de en lugar de la
tabla completa.
MySQL, PostgreSQL y SQLite admiten la cláusula LIMIT. Ora- cle
y SQL Server utilizan una sintaxis diferente con la misma
funcionalidad:
-- MySQL, PostgreSQL y SQLite SELECT
*
DEL propietario
LÍMITE 3;
-- Oracle
SELECT *
DEL propietario
DONDE ROWNUM <= 3;
-- SQL Server
La cláusula ORDER BY | 89
id nombre teléfono tipo
--- ---------------- ------------- --------
1 Pictured Rocks 906.387.2607 público
2 Naturaleza de 517.655.5655 privado
Michigan
3 AF LLC privado
La cláusula LIMITE | 89
CAPÍTULO 5
Crear, actualizar y borrar
La mayor parte de este libro trata sobre cómo leer datos de una
base de datos- con consultas SQL. La lectura es una de las cuatro
operaciones básicas de las bases de datos: crear, leer, actualizar y
eliminar (CRUD).
Este capítulo se centra en las tres operaciones restantes para
Bases de Datos, Tablas, Índices y Vistas. Además, la sección
Gestión de Transacciones cubre cómo ejecutar múltiples
comandos como una sola unidad.
Bases de datos
Una base de datos es un lugar donde almacenar datos de forma
organizada.
Dentro de una base de datos, puede crear objetos de base de
datos, que son cosas que almacenan o hacen referencia a datos.
Los objetos de base de datos comunes incluyen tablas,
restricciones, índices y vistas.
Un modelo de datos o un esquema describe cómo se organizan
los objetos de una base de datos .
La Figura 5-1 muestra una base de datos que contiene muchas
tablas. Los detalles sobre cómo se definen las tablas (por
ejemplo, la tabla Ventas contiene cinco columnas) y cómo se
conectan entre sí (por ejemplo, la columna customer_id de la
91
tabla Ventas coincide con la columna
93
Modelo de datos frente a esquema
Cuando se diseña una base de datos, primero se elabora un
modelo de datos, que es cómo se quiere organizar la base de
datos en a alto nivel. Podría parecerse a la Figura 5-1 e incluir los
nombres de las tablas, cómo están conectadas entre sí, etc.
Cuando esté listo para pasar a la acción, deberá crear un
esquema, que es la implementación del modelo de datos en una
base de datos. En el programa informático con el que trabajes,
deberás especificar las tablas, restricciones, claves primarias y
externas, etc.
NOTA
La definición de un esquema varía para algunos RDBMS.
En MySQL, un esquema es lo mismo que una base de
datos y los dos términos pueden utilizarse
indistintamente.
En Oracle, un esquema consiste en los objetos de la base
de datos propiedad de un usuario concreto, por lo que los
términos esquema y usuario se utilizan indistintamente .
NOTA
Te habrás dado cuenta de que el código actual de la base de
datos es el m i s m o q u e e l existente para Oracle y
SQLite.
Una instancia de Oracle sólo puede conectarse a una única
base de datos a l a v e z , y normalmente no se cambia
de base de datos.
Con SQLite, sólo puedes abrir y trabajar con un único
archivo de base de datos a la vez.
Bases de datos |
95
Cambiar a otra base de datos
Es posible que desee utilizar datos de otra base de datos o
cambiar a una base de datos recién creada. La Tabla 5-3 muestra
el código para cambiar a otra base de datos en cada RDBMS.
Tabla 5-3. Código para cambiar a otra base de datos
RDBMS Código
MySQL, USE otra_db;
Servidor
SQL
OracleTípicamente no cambias de base de datos (ver nota anterior), pero para
cambiar de usuario, escribirías: connect another_user
PostgreSQL \c otra_db
SQLite .abrir otra_db
ADVERTENCIA
Si elimina una b a s e de datos, perderá todos los datos
que contenga. No se puede deshacer, a menos que se haya
c r e a d o una copia de seguridad. Recomiendo no
ejecutar este comando a menos que esté 100% seguro de
que no necesita la base de datos.
Tabla 5-5. Tabla 5-5. Código para borrar una base de datos
RDBMS Código
MySQL, DROP DATABASE mi_nueva_db;
Oracle,
PostgreSQL,
SQL Server
SQLiteBorra el archivo .db en el explorador de archivos
Bases de datos |
97
NOTA
Oracle: Existen algunos pasos adicionales (relativos al
m o n t a j e , etc.) en torno a la sentencia DROP DATABASE
en Oracle, que pueden encontrarse en la documentación
de Oracle.
\c postgres
DROP DATABASE mi_nueva_db;
USE master;
go
DROP DATABASE
mi_nueva_db; go
Creación de tablas
Las tablas constan de filas y columnas, y almacenan todos los
datos de una base de datos. En SQL, existen algunos requisitos
adicionales para las tablas:
Creación de tablas | 97
NOTA
En SQLite, los datos de una columna no tienen por qué
ser todos d e l mismo tipo. SQLite es más flexible en el
sentido de que cada valor tiene asociado un tipo de datos,
en lugar de una columna entera.
Para ser compatible con otros RDBMSs, SQLite su- porta
columnas que tienen asignaciones de tipos de datos. Estas
afinidades de tipo son tipos de datos recomendados para
las columnas, y no son obligatorios.
id país nombre
--- -------- -------
1 EE.UU. Sam
2 EE.UU. Selena
3 CA Shawn
4 US Sutton
Al insertar filas de datos, el orden de los valores debe coincidir
exactamente con el orden de los nombres de las columnas.
Los valores de cualquier columna omitida de la lista de columnas
t o m a r á n su valor por defecto de NULL, a menos que
se especifique otro valor por defecto.
Creación de tablas | 99
NOTA
Necesita privilegios CREATE para crear una tabla. Si
obtiene un error al ejecutar el código anterior, no tiene
permiso para hacerlo y necesita hablar con el
administrador de su base de datos.
2. Cree una tabla con una clave externa que haga referencia a
la clave primaria de la otra tabla.
En este caso, estamos creando la tabla clientes donde la
columna order_id hace referencia a la clave primaria o_id
de la tabla pedidos:
CREAR TABLA clientes (
id INTEGER PRIMARY KEY,
order_id INTEGER,
name VARCHAR(15),
location VARCHAR(20),
FOREIGN KEY (order_id)
REFERENCES orders (o_id)
);
NOTA
La clave externa (order_id) y la clave primaria a la que
hace referencia (o_id) deben ser ambas del mismo tipo de
datos.
id país nombre
--- -------- -------
1 EE.UU. Sam
2 EE.UU. Selena
3 CA Shawn
4 US Sutton
Cree una nueva tabla con dos columnas:
CREATE TABLE
nueva_tabla_dos_columnas ( id
INTEGER,
nombre VARCHAR(15)
);
Inserta los resultados de una consulta en la nueva tabla:
INSERT INTO
nueva_tabla_dos_columnas (id,
nombre)
SELECT id, nombre
id nombre
--- -------
1 Sam
2 Selena
También puede insertar valores de una tabla existente y añadir
o modificar otros valores por el camino.
Cree una nueva tabla con cuatro columnas:
CREATE TABLE
nueva_tabla_cuatro_colum
nas ( id INTEGER,
nombre VARCHAR(15),
nueva_columna_num INTEGER,
nueva_columna_texto VARCHAR(30)
);
Inserta los resultados de una consulta en la nueva tabla y rellena
los valores de las nuevas columnas:
INSERT INTO nueva_tabla_cuatro_columnas
(id, name, new_num_column, new_text_column)
SELECT id, name, 2017, 'stargazing'
DESDE mi_tabla_simple
WHERE id = 2;
Inserta los resultados de una consulta en la nueva tabla y cambia
un valor de la fila (id en este caso):
INSERT INTO nueva_tabla_cuatro_columnas
(id, nombre, nueva_columna_num,
nueva_columna_texto) SELECT 3, nombre, 2017, 'lobos'
DESDE mi_tabla_simple
WHERE id = 2;
id nombre_nuevo_num_columna nuevo_texto_columna
--- ------- --------------- ----------------
2 Selena 2017 observación de estrellas
3 Selena 2017 lobos
id país nombre
--- -------- --------
5 CA Celine
6 CA Michael
7 EE.UU. Stefani
8 NULL Olivia
...
NOTA
Si MySQL le da un error que dice que la carga de datos
locales está deshabilitada, puede habilitarla actualizando
la variable global local_infile, saliendo y reiniciando
MySQL:
SET GLOBAL local_infile=1;
quit
Modificación de tablas
En esta sección se explica cómo cambiar el nombre de la tabla, las
columnas, las restricciones de y los datos de una tabla.
NOTA
Necesitas privilegios ALTER para modificar una tabla. Si
obtiene un error al ejecutar el código de esta sección, no
tiene permiso para hacerlo y debe hablar con el
administrador de su base de datos .
'nuevo_nombre_tabla';
Renombrar una
columna
El código de la Tabla 5-11 muestra cómo renombrar una columna en
cada RDBMS.
Tabla 5-11. Código para renombrar una columna
RDBMS Código
MySQL, ALTER TABLE mi_tabla
Oracle, RENAME COLUMN old_column_name
PostgreSQL, TO new_column_name;
SQLite
Servidor SQL EXEC sp_rename 'mi_tabla.antiguo_nombre_columna',
'nuevo_nombre_columna', 'COLUMNA';
Modificación de tablas |
117
Visualizar, añadir y eliminar columnas
Después de crear una tabla, puede ver, añadir y eliminar col-
umnas de la tabla.
NOTA
Si una columna tiene alguna restricción, primero debe eliminar las
restricciones de antes de eliminar la columna.
Modificación de tablas |
119
Modificaciones manuales en SQLite
SQLite no admite algunas modificaciones de tablas, como la
eliminación de columnas o la
adición/modificación/eliminación de restricciones.
Como solución alternativa, puede utilizar una interfaz gráfica
de usuario para generar código que modifique una tabla, o bien
crear manualmente una nueva tabla en y copiar los datos
(consulte los pasos siguientes).
1. Cree una nueva tabla con las columnas y restricciones que
desee.
CREAR TABLA mi_tabla_2 (
id INTEGER NOT NULL,
país VARCHAR(2),
nombre VARCHAR(30)
);
Modificación de tablas |
121
Tabla 5-15. Código para mostrar las restricciones de una tabla
RDBMSCode MySQL
SHOW CREAR TABLA mi_tabla;
Oracle SELECT *
FROM user_cons_columns
WHERE nombre_tabla = 'MI_tabla';
PostgreSQL \d mi_tabla
SQL Server -- Lista de restricciones (excepto las
predeterminadas) SELECT nombre_tabla,
nombre_restricción,
tipo_restricción
FROM esquema_informacion.restricciones_tabla
WHERE nombre_tabla = 'mi_tabla';
-- Listar todas las restricciones
por defecto SELECT
OBJECT_NAME(parent_object_id),
COL_NAME(parent_object_id,
parent_column_id),
definition
FROM sys.default_constraints
WHERE OBJECT_NAME(parent_object_id) =
'mi_tabla';
SQLite .esquema mi_tabla
NOTA
Oracle almacena los nombres de tablas y columnas en
mayúsculas, a menos que rodee el nombre de la columna
con comillas dobles. Al hacer referencia a un nombre de
tabla o de columna en una sentencia SQL, debe escribir el
nombre en mayúsculas (MI_TABLE).
Modificación de tablas |
123
El código de la Tabla 5-17 modifica las siguientes restricciones:
NOTA
En MySQL, CHECK puede sustituirse por DEFAULT, INDEX
(para restricciones UNIQUE), PRIMARY KEY y FOREIGN KEY.
Para eliminar una restricción NOT NULL, debe MODIFICAR la
restricción .
LOWER(nombre)
Modificación de tablas |
125
------------
celine
michael
stefani
Actualizar los valores de una columna de datos:
UPDATE mi_tabla
SET nombre = LOWER(nombre);
premios + 1
ADVERTENCIA
Es muy importante incluir una cláusula WHERE junto con
la cláusula SET cuando se actualizan filas específicas de
datos. Sin la cláusula WHERE, se actualizaría toda la tabla .
Modificación de tablas |
127
EE.UU.
MIN(premios)
------------
4
Actualizar valores a partir de una consulta:
UPDATE mi_tabla
SET premios = (SELECT MIN(premios) FROM mi_tabla)
WHERE país = 'CA';
NOTA
MySQL no permite actualizar una tabla con una consulta
sobre la misma tabla. En el ejemplo anterior, no puede
tener UPDATE mi_tabla y FROM mi_tabla. El e s t a d o
se ejecutará si realiza una consulta FROM otra_tabla.
Modificación de tablas |
129
Borrar una tabla
Cuando ya no necesite una tabla, puede eliminarla mediante una
sentencia DROP TABLE:
DROP TABLE mi_tabla;
En MySQL, PostgreSQL, SQL Server y SQLite, también puede
añadir IF EXISTS para evitar un mensaje de error si la tabla no
existe:
DROP TABLE IF EXISTS mi_tabla;
ADVERTENCIA
Si elimina una tabla, perderá todos los datos que
contenga. No se puede deshacer, a menos que se haya
creado una copia de seguridad. Recomiendo no ejecutar
este comando a menos que esté 100% seguro de que no
necesita la tabla.
Índices
Imagine que tiene una tabla con 10 millones de filas. Escribes
una consulta en la tabla para devolver los valores que se
registraron el 2021-01-01:
SELECCIONAR *
FROM mi_tabla
WHERE log_date = '2021-01-01';
Esta consulta tardaría mucho tiempo en ejecutarse. La razón es
que, entre bastidores, se comprueba cada fila para ver si log_date
coincide con 2021-01-01 o no. Son 10 millones de
comprobaciones.
Para acelerar este proceso, puede crear un índice en la columna
log_date. Esto es algo que harías una sola vez, y todas las
consultas futuras podrían beneficiarse de ello.
Índices | 129
Tabla 5-20. Comparación entre el índice del libro y el índice SQL
Tabla BookSQL
TérminosUn libro tiene muchas páginas. Una tabla tiene muchas filas.
Cada página tiene atributos Cada fila tiene columnas, entre ellas
que incluyen el recuento de customer_id, log_date, etc.
palabras, los conceptos
tratados, etc. Está consultando una tabla y
EscenarioEstás leyendo este d e s e a encontrar todas las filas
libro y en las que log_date es 2021-
desea encontrar todas las 01-01.
páginas sobre el concepto
subconsultas.
El Podrías empezar desde la Podría empezar por la fila 1 y
enfoque página 1 y hojear cada recorrer todas las filas para ver
lento página de este libro para ver si la fecha de registro
si se mencionan o no las es
subconsultas. Esto llevaría 2021-01-01 o no. Esto llevaría
mucho tiempo. mucho tiempo.
Crear un Se ha creado un índice para Se ha creado un índice en la
índice todos los conceptos de este columna log_date de la tabla.
libro. Cada concepto se Cada log_date aparece en el
enumera en el índice junto índice junto con los números de
con los números de página fila que contienen la log_date.
El que hablan del concepto. Para encontrar filas con una
enfoque Para encontrar páginas sobre log_date de 2021-01-01, la
rápido subconsultas, puedes ir al consulta utiliza el índice para
índice para encontrar encontrar rápidamente los
rápidamente los números de números de fila que contienen la
página que hacen referencia a fecha y devolver esas filas.
las subconsultas e ir a esas
páginas.
Índices | 131
CONSEJO
Es una buena idea crear un índice en algunas columnas
sobre las que se filtra a menudo. Por ejemplo, la columna
de clave primaria, la columna de fecha, etc.
Sin embargo, no conviene crear un índice para
demasiadas c o l u m n a s , porque ocupa espacio.
Además, cada vez que se añadan o eliminen filas, habrá
q u e reconstruir el índice, lo que lleva mucho tiempo.
NOTA
Al crear un índice en Oracle, debe escribir el nombre de la
columna en mayúsculas y entre comillas:
CREATE INDEX my_index ON my_table
('LOG_DATE');
Oracle crea automáticamente un índice para PRIMARY KEY y
Columnas UNIQUE cuando se crea una tabla.
NOTA
Necesita privilegios CREATE para crear un índice. Si
obtiene un error al ejecutar el código anterior, no tiene
permiso para hacerlo y necesita hablar con el
administrador de su base de datos.
Borrar un índice
El código de la Tabla 5-21 muestra cómo borrar un índice en cada
RDBMS .
Tabla 5-21. Código para borrar un índice
RDBMS Código
MySQL, SQL Server DROP INDEX mi_índice ON mi_tabla;
Oracle, PostgreSQL, SQLite DROP INDEX my_index;
ADVERTENCIA
La eliminación de un índice no se puede deshacer.
Asegúrate al 100% de que quieres borrar un índice antes de
eliminarlo.
El lado positivo es que no hay pérdida de datos. Los datos
de la tabla no se ven afectados y siempre se puede volver a
crear el índice.
Índices | 133
Vistas
Imagina que tienes una consulta SQL larga y compleja que
incluye muchas uniones, filtros, agregaciones, etc. Los resultados
de la c o n s u l t a te resultan útiles y quieres volver a
consultarlos más adelante.
Esta es una situación ideal para crear una vista, o dar un nombre
a la salida de una consulta. Recuerde que el resultado de una
consulta es una única tabla, por lo que una vista tiene el mismo
aspecto que una tabla. La diferencia es que la vista no contiene
datos como una tabla, sino que hace referencia a los datos.
NOTA
A veces, los administradores de bases de datos (DBA)
crean vistas en para restringir el acceso a las tablas.
Imaginemos que existe una tabla de clientes. La mayoría
de la gente sólo debería poder leer los datos de la tabla,
pero no modificarlos.
El DBA puede crear una vista de cliente que incluya
datos idénticos a los de la tabla de clientes. Ahora, todo
el mundo puede consultar la vista de cliente, y sólo el
DBA podría editar los datos dentro de la tabla de
clientes.
Vistas | 133
2 Naturaleza de Michigan 3
3 AF LLC 1
4 MI DNR 1
5 Cataratas Horseshoe 0
AVG(número_cascadas)
--------------------
1.6
-- Ver enfoque
CREAR VISTA owner_waterfalls_vw COMO
SELECT o.id, o.name,
COUNT(w.id) AS num_waterfalls
FROM owner o LEFT JOIN waterfall w
ON o.id = w.owner_id
GROUP BY o.id, o.name;
SELECT AVG(num_waterfalls)
FROM owner_waterfalls_vw;
AVG(número_cascadas)
--------------------
1.6
id país nombre
--- -------- ------
1 EE.UU. Anna
2 EE.UU. Emily
3 EE.UU. Molly
Vistas | 135
Crea una vista:
CREAR VISTA mi_vista COMO
SELECT *
FROM mi_tabla
WHERE country = 'US';
Consulta la vista:
SELECT * FROM mi_vista;
id país nombre
--- -------- ------
1 EE.UU. Anna
2 EE.UU. Emily
3 EE.UU. Molly
ADVERTENCIA
No se puede deshacer la eliminación de una vista. Asegúrese
al 100% de que desea eliminar una vista antes de eliminarla.
El lado positivo es que no hay pérdida de datos. Los datos
siguen estando en la tabla original, y siempre se puede
volver a crear la vista.
Vistas | 137
Gestión de transacciones
Una transacción permite actualizar una base de datos de forma
más segura. Consiste en una secuencia de operaciones que se
ejecutan como una sola unidad. O se ejecutan todas las
operaciones o no se ejecuta ninguna, lo que también se conoce
como atomicidad.
El siguiente código inicia una transacción antes de realizar
cualquier cambio en las tablas de . Una vez ejecutadas las
sentencias, no se realizan actualizaciones permanentes en la base
de datos hasta que se confirman los cambios:
INICIAR TRANSACCIÓN;
COMPROMETERSE;
Vistas | 139
asegure sus cambios con un COMMIT. Si algo parece
mal y quieres volver a dejar las cosas como estaban antes
de la transacción, puedes hacerlo con un ROLL BACK.
+------+----------------+
| id | Título |
+------+----------------+
| 1 |
| 2 | Born a Crime |
| 3. Bossypants |
+------+----------------+
+------+----------------+
| id | Título |
+------+----------------+
| 2 | Born a Crime |
+------+----------------+
+------+----------------+
| id | Título |
+------+----------------+
| 1 |
| 3. Bossypants |
+------+----------------+
+------+----------------+
| id | Título |
+------+----------------+
| 1 |
| 2 | Born a Crime |
| 3. Bossypants |
+------+----------------+
+------+----------------+
| id | Título |
+------+----------------+
143
Tabla 6-1. Tipos de datos en SQL Tipos de datos en SQL
Numérico Cadena Fecha y hora Otros
Entero (123) Carácter Fecha Boolean
Decimal (1.23) ('hola') ('2021-12-01') o
Punto flotante Unicode (' Hora ('2:21:00') (TRUE)
(1.23e10) 西瓜')
Fecha ('2021- Binario
12-01 (imágenes,
2:21:00') documentos,
etc.)
El literal NULL
Las celdas sin valor se representan mediante la palabra clave
NULL (también conocida como el literal NULL), que no distingue
entre mayúsculas y minúsculas (NULL = Null = null).
A menudo verá valores nulos en una tabla, pero nulo en sí no es
un tipo de dato. Cualquier columna numérica, de cadena, de
fecha y hora o de otro tipo puede incluir valores nulos dentro
de la columna.
CONSEJO
Si ya ha creado una tabla pero desea cambiar el tipo de
datos de una columna, puede hacerlo modificando la
restricción de la c o l u m n a con una sentencia ALTER
TABLE. Encontrará más información en Modificación de
una restricción, en el Capítulo 5.
Valores numéricos
Los valores numéricos incluyen números enteros, d e c i m a l e s
y de coma flotante.
Valores enteros
Los números sin decimal se tratan como enteros. El signo + es
opcional.
123 +123-123
Valores decimales
Los decimales incluyen un punto decimal y se almacenan como
valores exactos . El signo + es opcional.
123.45 +123. 45-123.45
+-------------------+
| mi_columna_integral |
+-------------------+
|25 |
|-525 |
|2500252 |
+-------------------+
La Tabla 6-4 lista las opciones de tipos de datos enteros para cada
RDBMS.
La Tabla 6-6 lista las opciones de tipos de datos decimales para cada
RDBMS.
Tabla 6-6. Tipos de datos decimales Tipos de datos decimales
RDBMSData TypeDígitos máximos permitidos
Por defecto
MySQL DECIMAL o Total: 65 DECIMAL(10,0)
NÚMERO Después del punto
decimal: 30
Oracle NÚMERO Total: 38 0 dígitos
Después del punto decimal: después del
-84 a 127 (negativo punto
significa antes del punto decimal
decimal)
PostgreSQL DECIMAL o Antes del punto decimal: DECIMAL(30,6)
NÚMERO 131,072
Después del punto
SQL Server DECIMAL o decimal: 16,383 DECIMAL(18,0)
NÚMERO Total: 38
Después del punto
decimal: 38
SQLite NUMÉRICO Sin entradasNo por defecto
• Número: 1234.56789
• Notación en coma flotante: 1.23 x 10^3
+-----------------+----------------------+
| mi_columna_flotante mi_columna_doble |
+-----------------+----------------------+
|123 .45 |123 .45 |
|-12345. 7 |-12345 .6789 |
|1234570 | 1234567.8901234567 |
Cadena de datos
Esta sección presenta los valores de cadena para darle una idea
de cómo se representan en SQL y, a continuación, entra en
detalle en los tipos de datos char- acter y unicode.
Las columnas con datos de cadena pueden introducirse en
funciones de cadena como LENGTH() y REGEXP() (expresión
regular), que se tratan en la sección Funciones de cadena del
capítulo 7.
Valores de cadena
Los valores de cadena son secuencias de caracteres que incluyen
letras, números y caracteres especiales.
Conceptos básicos
La norma es encerrar los valores de cadena entre comillas simples:
'Esto es una cadena'.
Utilice dos comillas simples adyacentes cuando necesite
incrustar una sola comilla en una cadena:
CONSEJO
Como práctica recomendada, las comillas simples ('')
deben utilizarse para encerrar valores de cadena, mientras
que las comillas dobles ("") deben utilizarse para los
identificadores (nombres de tablas, columnas, etc.).
Secuencias de escape
MySQL y PostgreSQL soportan secuencias de escape, o una
secuencia especial de texto que tiene significado. La Tabla 6-8
lista las secuencias de e s c a p e más comunes.
Cadena de datos |
155
Tabla 6-8. Secuencias de escape comunes
Secuencia de Escape Descripción
\' Cita simple
\t Tab
\n Nueva línea
\r Retorno de carro
\b Retroceso
\\ Barra diagonal inversa
+-------+--------+--------------+
| hola | he'llo |hello |
+-------+--------+--------------+
PostgreSQL le permite incluir secuencias de escape en cadenas si
la cadena en general está precedida por una E o e:
SELECT 'hola', E'he\'llo', e'\thello';
----------+----------+---------------
Hola. | hola
Las secuencias de escape sólo se aplican a las cadenas encerradas
entre comillas simples y no a las cadenas encerradas entre signos
de dólar.
Cadena de datos |
157
INSERT INTO mi_tabla VALUES
('Aquí hay algo de texto'),
('Y algunos números - 1 2 3 4 5'),
('¡Y algunos signos de puntuación!
:)');
+------------------------------+
| mi_columna_carácter |
+------------------------------+
| Aquí hay algo de texto. |
| Y algunos números - 1 2 3 4 5 |
| Y algunos signos de puntuación. :) |
+------------------------------+
Existen tres tipos principales de datos de caracteres:
VARCHAR (carácter variable)
Este es el tipo de datos de cadena más popular. Si el tipo de
datos es VARCHAR(50), entonces la columna permitirá hasta
50 caracteres . En otras palabras, la longitud de la cadena es
variable. En otras palabras, la longitud de la cadena es
variable.
CHAR (carácter)
Si el tipo de datos es CHAR(5), entonces cada valor de la
columna tendrá exactamente 5 caracteres. En otras
palabras, la longitud de la cadena es fija. Los datos se
rellenarán con espacios a la derecha para que tengan
exactamente la longitud especificada. Por ejemplo, 'hi' se
almacenaría como 'hi '.
TEXT
O A diferencia de VARCHAR y CHAR, TEXT no requiere entradas,
lo que significa que no tiene que especificar una longitud
para el texto. Es útil para almacenar cadenas largas, como
un párrafo o más de texto.
La Tabla 6-9 enumera las opciones de tipos de datos de caracteres para
cada RDBMS.
Cadena de datos |
159
TEXTO Sin entradas Sin entradas 2,147,483,647
bytes
SQLite TEXTO Sin entradas Sin entradas Varía
Cadena de datos |
161
El siguiente código muestra la diferencia entre VARCHAR
y NVARCHAR (Unicode):
CREAR TABLA mi_tabla (
ascii_texto VARCHAR(10),
unicode_texto NVARCHAR(10)
);
+------------+ ---------------+
| ascii_text | unicode_text |
+------------+ ---------------+
| abc| abc |
| 赵欣婉 |
+------------+ ---------------+
NOTA
Al insertar datos Unicode de un archivo de texto en una
columna NVARCHAR, los valores Unicode del archivo de
texto no necesitan el prefijo N.
Valores de fecha
Una columna de fecha debe tener valores de fecha en el formato
AAAA- MM-DD. En Oracle, el formato por defecto es DD-
MON-AAAA.
El 15 de octubre de 2022 está escrito como:
'2022-10-15'
En Oracle, el 15 de octubre de 2022 se escribe como:
15-OCT-2022
Cuando se hace referencia a un valor de fecha en una consulta, se
debe anteponer a la cadena una palabra clave DATE o CAST para
NOTA
En Oracle, el formato de fecha después de la palabra clave
DATE es diferente del formato de fecha dentro de la
función CAST.
Además, en Oracle, cuando se realiza un cálculo o se busca
una variable del sistema que sólo contiene una cláusula
SELECT, es necesario añadir FROM dual al final de la
consulta. dual es una tabla ficticia que contiene un único
valor.
SELECT DATE '2021-02-25' FROM dual;
SELECT CURRENT_DATE FROM dual;
Valores temporales
Una columna de tiempo debe tener valores de tiempo en el formato
hh:mm:ss. 10:30 a.m. se escribe como:
'10:30:00'
Datos de fecha y hora |
163
También puede incluir segundos más granulares, de hasta seis
decimales:
'10:30:12.345678'
También puede añadir una zona horaria. La hora estándar
central también se conoce como UTC-06:00:
'10:30:12.345678 -06:00'
Cuando se hace referencia a un valor de tiempo en una consulta,
se debe anteponer a la cadena una palabra clave TIME o CAST
para indicar a SQL que se trata de un tiempo, como se muestra
en la Tabla 6-12.
Tabla 6-12. Referencia a una hora en una consulta
RDBMSCode MySQL
SELECT HORA '10:30';
SELECT HORA('10:30');
SELECT CAST('10:30' AS TIME);
Oracle SELECT TIME '10:30:00' FROM dual;
SELECT CAST('10:30' AS TIME) FROM
dual;
PostgreSQL SELECT TIEMPO '10:30';
SELECT CAST('10:30' AS TIME);
SQL Server SELECT CAST('10:30' AS TIME);
SQLite SELECT HORA('10:30');
NOTA
En Oracle, el formato de tiempo después de la palabra clave
TIME debe incluir también los segundos.
+------------+----------+ -----------------------+
| dt| tm| dttm |
+------------+----------+ -----------------------+
+---------------------+ --------+
| ts| yr |
+---------------------+ --------+
| 2021-01-29 12:56:20 | 2021 |
+---------------------+ --------+
La Tabla 6-14 enumera las opciones comunes del tipo de datos
datetime en MySQL.
Tabla 6-14. Tipos de datos datetime de MySQL
Tipo de datos Formato Rango
DATEYYY-MM-DD1000-01-01 a 9999-12-31
HORA hh:mm:ss-838 :59:59 a 838:59:59
FECHA AAAA-MM-DD 1000-01-01 00:00:00 a 9999-12-31
hh:mm:ss 23:59:59
TIMESTAMP AAAA-MM-DD 1970-01-01 00:00:01 UTC a 2038-01-19
hh:mm:ss 03:14:07 UTC
AÑO AAAA0000 a 9999
NOTA
Tanto DATETIME como TIMESTAMP almacenan fechas y
horas. La diferencia es que DATETIME no tiene una zona
horaria asociada, mientras que TIMESTAMP almacena
valores Unix (un punto específico en el tiempo) y se
utiliza a menudo para anotar cuándo se crea o actualiza
un registro.
DT TS
------------ -------------------------------
04-JUL-2104-JUL-21 06.30.00.000000 AM
TS_TZ
--------------------------------------
04-JUL-21 06.30.45.000000 AM CST
TS_LC
-------------------------------
04-JUL-21 06.30.00.000000 AM
La Tabla 6-15 lista las opciones comunes de tipos de datos datetime en
Oracle.
Tabla 6-15. Tipos de datos datetime de Oracle
Tipo de datos Descripción
DATECuede almacenar sólo la fecha o la fecha y la hora si el
NLS_DATE_FORMAT se actualiza
TIMESTAMPLike DATE, but adds fractional seconds (the
default is six digits, but can go up to nine digits after the
decimal point)
MARCA HORARIA Como TIMESTAMP, pero añade la zona horaria
CON ZONA
HORARIA
Como TIMESTAMP WITH TIME ZONE, pero se ajusta en
MARCA HORARIA f u n c i ó n d e la zona horaria local del usuario.
CON ZONA
HORARIA LOCAL
VALOR
---------------------------
DD-MON-RR
DD-MON-RR HH.MI.SSXFF AM
Para cambiar el formato de la fecha o de la hora, puede modificar la
opción
Parámetro NLS_DATE_FORMAT o NLS_TIMESTAMP_FORMAT.
El siguiente código cambia el actual NLS_DATE_FORMAT = DD-MON-
RR para incluir también la hora:
ALTERAR SESIÓN
SET NLS_DATE_FORMAT = 'AAAA-MM-DD HH:MI:SS';
En la Tabla 7-27 se pueden encontrar otros símbolos comunes
para fecha y hora, como AAAA para año y HH para hora:
Especificadores de fecha y hora.
dt | tm | tm_tz |
------------+----------+ ---------------+
2021-07-04 | 06:30:00 | 06:30:00-06 |
ts | ts_tz
---------------------+------------------------
2021-12-25 07:00:01 | 2021-12-25 07:00:01-06
La Tabla 6-16 enumera las opciones comunes de tipo de datos
datetime en PostgreSQL.
Tabla 6-16. Tipos de datos datetime de PostgreSQL
Tipo de datos Formato Rango
FECHAAAA-MM-DD4713 a.C. a 5874897 d.C.
HORA hh:mm:ss00 :00:00 a 24:00:00
HORA CON HUSO HORARIO hh:mm:ss+tz00 :00:00+1459 a 24:00:00-1459
FECHA AAAA-MM-DD 4713 a.C. a 294276 d.C.
hh:mm:ss
MARCA HORARIA AAAA-MM-DD 4713 a.C. a 294276 d.C.
CON ZONA hh:mm:ss+tz
HORARIA
dt tm
------------- ---------------------
2021-07-04 06:30:00.00000000
dttm_sm
-----------------------
2021-12-25 07:00:00
dttm
---------------------------
2021-12-25 07:00:01.000
dttm2
------------------------------
2021-12-25 07:00:01.0000000
dttm_off
-------------------------------------
2021-12-25 07:00:01.0000000 -06:00
La Tabla 6-17 enumera las opciones comunes de tipo de datos
datetime en SQL Server.
Tabla 6-17. Tipos de datos datetime de SQL Server
Tipo de datos Formato Rango
DATEYYY-MM-DD0001-01-01 a 9999-12-31
HORA hh:mm:ss00 :00:00.0000000 a 23:59:59.9999999
SMALLDATETIME AAAA-MM-DD Fecha: 1900-01-01 a 2079-06-06
hh:mm:ss Hora: de 0:00:00 a 23:59:59
FECHA AAAA-MM-DD Fecha: 1753-01-01 a 9999-12-31
hh:mm:ss Hora: de 00:00:00 a 23:59:59.999
FECHA2 AAAA-MM-DD Fecha: 0001-01-01 a 9999-12-31
hh:mm:ss Hora: de 00:00:00 a 23:59:59.9999999
NOTA
Aunque en SQLite no existen tipos de datos datetime
específicos, las funciones datetime como DATE(), TIME()
y DATETIME() permiten trabajar con fechas y horas en
SQLite.
Encontrará más información en la s e c c i ó n Funciones
de fecha y hora del capítulo 7.
dt_text|dt_real
2021-12-25 7:00:01|2021-12-25 7:00:01
Otros datos
Hay muchos otros tipos de datos en SQL, incluyendo algunos
que son específicos de cada RDBMS.
Algunos de ellos pertenecen a una de las categorías existentes de
tipos de datos, pero capturan datos más detallados, como el tipo
numérico MONEY o el tipo datetime INTERVAL.
Otros capturan datos más complejos, como datos geoespaciales
que señalan una ubicación concreta en la Tierra o datos web
almacenados en formatos JSON/XML.
Esta sección cubre dos tipos de datos adicionales: Datos
booleanos y datos de archivos externos.
Datos booleanos
Los dos valores booleanos son TRUE y FALSE. No distinguen entre
mayúsculas y minúsculas y deben escribirse sin comillas:
SELECCIONE VERDADERO, Verdadero, FALSO, Falso;
+------+------+-------+ ---------+
|1 |1 |0 |0 |
+------+------+-------+ ---------+
+-------------------+
| mi_columna_booleana |
+-------------------+
|1 |
|0 |
|1 |
+-------------------+
Oracle y SQL Server no tienen tipos de datos booleanos, pero
existen soluciones:
+----------+----------+ ----------+
| 0xAF12 0xAF12 0xAF12
+----------+----------+ ----------+
MySQL admite los tres formatos. PostgreSQL admite los dos
primeros formatos. SQL Server y SQLite soportan el tercer
formato.
En Oracle, aunque no se puede mostrar fácilmente un v a l o r
hexadecimal, se puede utilizar la función TO_NUMBER para
mostrar un valor hexadecimal como un número: SELECT
TO_NUMBER('AF12', 'XXXX') FROM dual; la X representa la
notación hexadecimal.
NOTA
En Oracle y SQL Server, la cadena ae$ iou no se
reconoce automáticamente como un valor binario y debe
convertirse en uno antes de insertarse en una tabla.
-- Oracle
SELECT RAWTOHEX('ae$ iou') FROM dual;
-- SQL Server
SELECT CONVERT(VARBINARY, 'ae$ iou');
La Tabla 6-19 lista las opciones de tipos de datos binarios para cada
RDBMS.
179
Además de las sentencias SELECT, los operadores y funciones
también pueden utilizarse en las sentencias INSERT, UPDATE y
DELETE.
Operadores
Los operadores pueden ser símbolos o palabras clave. Pueden
realizar cálculos (+) o comparaciones (BETWEEN). Esta sección
181
Operadores lógicos
Los operadores lógicos se utilizan para modificar condiciones,
cuyo resultado en es TRUE, FALSE o NULL. Los operadores lógicos
del bloque de código (NOT, AND, OR) aparecen en negrita:
SELECCIONAR *
DE empleados
WHERE fecha_inicio NO ES NULA
AND (title = 'analista' OR pay_rate < 25);
CONSEJO
Cuando se utilizan AND y OR para combinar varias
sentencias condicionales, conviene indicar claramente el
orden de las operaciones con paréntesis: ().
Operadores | 181
Tabla 7-4. Ejemplo NOT
nombre nombre IN name NOT IN ('Henry',
('Henry', Harper")
Harper")
Henry TRUE FALSO
Lily FALSO TRUE
NULO NULL NULL
Operadores de comparación
Los operadores de comparación se utilizan en predicados.
NOTA
MySQL también permite <=>, que es una prueba de
igualdad a prueba de nulos.
Cuando se utiliza =, si se comparan dos valores y uno de
ellos es NULL, el valor resultante es NULL.
Cuando se utiliza <=>, si se comparan dos valores y uno
de ellos es NULL, el valor resultante es 0. Si ambos son
NULL, el valor resultante es 1.
Operadores | 183
Tabla 7-7. Operadores de comparación (palabras clave)
OperatorDescription
BETWEEN Comprueba si un valor se encuentra dentro de un
rango determinado EXISTS
Comprueba si existen filas en una subconsulta
EN Comprueba si un valor está contenido en una lista de valores
IS NULL Comprueba si un valor es nulo o no
LIKE Comprueba si un valor coincide con un patrón simple
NOTA
El operador LIKE se utiliza para encontrar patrones
sencillos, como por ejemplo, texto que empiece por la
letra A. E n c o n t r a r á más información en la sección
LIKE.
Las expresiones regulares se utilizan para buscar
p a t r o n e s más complejos, como extraer cualquier
texto situado entre dos signos de puntuación. Encontrará
más información en la sección de expresiones regulares.
ENTRE
Utilice ENTRE para comprobar si un valor se encuentra dentro de
un intervalo. BETWEEN es una combinación de >= y <=. El menor
de los dos valores siempre debe escribirse primero, con el
operador AND separando los dos.
Encontrar todas las filas en las que las edades son mayores o
iguales que 35 y menores o iguales que 44:
SELECCIONAR *
FROM mi_tabla
cuando la edad esté comprendida entre 35 y 44 años;
EXISTE
Utilice EXISTS para comprobar si una subconsulta devuelve
resultados o no. Normalmente, la subconsulta hace referencia a
otra tabla.
La siguiente consulta devuelve los empleados que también son
clientes:
SELECT e.id, e.name
FROM empleados e
WHERE EXISTS (SELECT *
DE clientes c
WHERE c.email = e.email);
Operadores | 185
La siguiente consulta devuelve los clientes que nunca han realizado
una compra:
SELECT c.id, c.name
FROM clientes c
WHERE NOT EXISTS (SELECT *
FROM pedidos o
WHERE o.email = c.email);
EN
Utilice IN para comprobar si un valor se encuentra
dentro de una lista de valores. La siguiente consulta
devuelve los valores de unos cuantos empleados:
SELECCIONAR *
DE empleados
WHERE e.id IN (10001, 10032, 10057);
La siguiente consulta devuelve los empleados que no han disfrutado
de un día de vacaciones:
SELECT e.id
FROM empleados e
WHERE e.id NOT IN (SELECT v.emp_id
DESDE vacaciones v);
ADVERTENCIA
Cuando se utiliza NOT IN, si hay un solo valor NULL en la
columna de la subconsulta (v.emp_id en este caso), la
subconsulta nunca será TRUE, lo que significa que no se
devolverá ninguna fila .
Si hay valores potencialmente NULL en la columna de la
subconsulta, es mejor utilizar NOT EXISTS:
SELECT e.id
FROM empleados e
WHERE NOT EXISTS (SELECT *
DESDE vacaciones v
WHERE v.emp_id = e.id);
COMO
Utilice LIKE para hacer coincidir un patrón simple. El signo de
porcentaje (%) es un comodín de que significa uno o más caracteres.
He aquí una tabla de muestra:
SELECT * FROM mi_tabla;
+------+ --------------------+
| id| txt |
+------+ --------------------+
|Eres genial. |
|Gracias. |
|3 | Pensando en ti. |
|Estoy 100% seguro. |
+------+ --------------------+
Busca todas las filas que contengan el término tú:
SELECCIONAR *
FROM mi_tabla
WHERE txt LIKE '%you%';
Operadores | 187
-- Resultados de MySQL, SQL Server y SQLite
+------+ ------------------+
| id| txt |
+------+ ------------------+
|Eres genial. |
|Gracias. |
|3 | Pensando en ti. |
+------+ ------------------+
+------+ ----------------+
| id| txt |
+------+ ----------------+
|Eres genial. |
+------+ ----------------+
Utilice NOT LIKE para devolver filas que no contengan los caracteres.
En lugar del signo de porcentaje (%) para que coincida con
uno o más c a r a c t e r e s , puede utilizar el guión bajo ( _ ) para
que coincida exactamente con un carácter .
+------+ --------------------+
| id| txt |
+------+ --------------------+
|Estoy 100% seguro. |
+------+ --------------------+
Después de la palabra clave ESCAPE, hemos declarado !
como carácter de escape, de modo que cuando se pone !
delante del % medio en
%!%%, !% se interpreta como %.
Operadores matemáticos
Los operadores matemáticos son símbolos matemáticos que
pueden utilizarse en SQL. El operador matemático en el bloque
de código (/) está en negrita:
SELECT salario / 52 AS
salario_semanal FROM mi_tabla;
La Tabla 7-8 lista los operadores matemáticos en SQL.
Operadores | 189
Tabla 7-8. Operadores matemáticos
Operador Descripción
+ Adición
- Resta
* Multiplicación
/ División
% Módulo (resto)
(MOD en
Oracle)
NOTA
En PostgreSQL, SQL Server y SQLite, dividir un entero por
un entero da como resultado un número entero:
SELECCIONE
15/2; 7
Si desea que el resultado incluya decimales, puede dividir
por un decimal o utilizar la función CAST:
SELECCIONAR
15/2.0; 7.5
-- PostgreSQL y SQL Server
SELECT CAST(15 AS DECIMAL) /
CAST(2 COMO
DECIMAL); 7.5
-- SQLite
SELECT CAST(15 COMO REAL)
/ CAST(2 COMO
REAL);
7.5
Funciones agregadas
Una función de agregado realiza un cálculo sobre muchas filas de
datos y da como resultado un único valor. En la Tabla 7-9 se
enumeran las cinco funciones de agregación básicas de en SQL.
Tabla 7-9. Funciones básicas de los agregados
Descripción de la función
COUNT() Cuenta el número de
valores SUM()
Calcula la suma de una columna
AVG() Calcula la media de una columna
MIN() Calcula el mínimo de una columna
MAX() Obtiene el máximo de una columna
ADVERTENCIA
Si decide incluir columnas agregadas y no agregadas en la
secuencia SELECT, debe incluir todas las columnas no
a g r e g a d a s en la cláusula GROUP BY (región en el
ejemplo anterior).
Algunos RDBMS arrojarán un error si no lo hace. Otros
RDBMS (como SQLite), no arrojarán un error y
permitirán que la sentencia se ejecute, aunque los
resultados devueltos sean inexactos. Es una buena práctica
volver a comprobar los resultados para asegurarse de que
tienen sentido.
+--------+------+------+------+ -----------+
| Nombre | q1 | q2 | q3 | q4 |
+--------+------+------+------+ -----------+
| Ali | 100 | 200 | 150 | NULL |
| Perno | 350 | 400 | 380 | 300 |
| Jordan | 200 | 250 | 300 | 320 |
+--------+------+------+------+ -----------+
+--------+--------------+
| Nombre | most_miles |
+--------+--------------+
| Ali | NULL
| Perno | 400 |
| Jordania | 320 |
+--------+--------------+
Funciones numéricas
Las funciones numéricas pueden aplicarse a columnas con tipos
de datos numéricos. Esta sección cubre las funciones numéricas
comunes en SQL.
NOTA
SQLite sólo admite la función ABS. Las demás
funciones matemáticas deben activarse
manualmente. E n c o n t r a r á más información en la
página de funciones matemáticas del sitio web de SQLite.
NOTA
SQLite sólo admite la función ROUND. Las demás opciones
de redondeo deben activarse manualmente. Puedes
e n c o n t r a r más detalles en la página de funciones
matemáticas del sitio web de SQLite.
id | str_col
----+---------
2 | 5.5
3 | 7.8
NOTA
El uso de CAST no cambia permanentemente el tipo de
datos de la columna; sólo lo hace mientras dura la
consulta. Para cambiar permanentemente el tipo de datos
de una columna, puede modificar la tabla.
Funciones de cadena
Las funciones de cadena pueden aplicarse a columnas con tipos de
datos de cadena . Esta sección cubre las operaciones de cadena
comunes en SQL.
Funciones de cadena |
199
En la cláusula SELECT:
SELECT LENGTH(nombre)
FROM mi_tabla;
En la cláusula WHERE:
SELECCIONAR *
FROM mi_tabla
WHERE LENGTH(nombre) < 10;
En SQL Server, utilice LEN en lugar de LENGTH.
NOTA
La mayoría de los RDBMS excluyen los espacios finales al
calcular la longitud de una cadena, mientras que Oracle
los incluye.
Ejemplo de cadena: 'Al '
Longitud: 2
Longitud en Oracle: 5
Para excluir los espacios finales en Oracle, utilice la función TRIM:
SELECT LENGTH(TRIM(nombre))
FROM mi_tabla;
+----------------+
| Color |
+----------------+
| . |
| ...¡naranja! |
| ..amarillo.. |
+----------------+
+-------------+
| color_clean |
+-------------+
| . |
| ...¡naranja! |
| ..amarillo.. |
+-------------+
Funciones de cadena |
201
SELECT TRIM('!' FROM color) AS color_clean
FROM mi_tabla;
+-----------------+
| Color_clean |
+-----------------+
| Rojo |
| .orange |
| ..amarillo.. |
+-----------------+
En SQLite, utilice TRIM(color, '!') en su lugar.
+ ----------------+
| Color_clean |
+ ----------------+
| Rojo |
| ...¡naranja! |
| ..amarillo.. |
+ ----------------+
+ -------------+
| color_clean |
+ -------------+
| Rojo |
| ¡Naranja! |
| amarillo.. |
+ -------------+
Concatenar cadenas
Utilice la función CONCAT o el operador de concatenación (||).
-- MySQL, PostgreSQL y SQL Server SELECT
CONCAT(id, '_', name) AS id_name FROM
my_table;
+-----------+
| Nombre_id |
+-----------+
| 1_Botas |
| 2_Pumpkin |
| 3_Tiger |
+-----------+
Funciones de cadena |
203
Enfoque 1: ¿Aparece o no el texto en la cadena?
Utilice el operador LIKE para determinar si el texto aparece
en una cadena o no. Con la siguiente consulta, sólo se
devolverán las filas que contengan el texto some:
SELECCIONAR *
FROM mi_tabla
WHERE mi_texto LIKE '%alguno%';
+---------------+
| alguna_ubicacion |
+---------------+
|9 |
|5 |
|5 |
+---------------+
Funciones de cadena |
205
NOTA
En Oracle, las expresiones regulares también se pueden
utilizar para buscar una subcadena utilizando
REGEXP_INSTR. Más detalles en la sección de expresiones
r e g u l a r e s en Oracle.
-- MySQL
SUBSTR(cadena FROM inicio POR longitud)
-- MySQL y PostgreSQL
SUBSTRING(cadena FROM inicio PARA
longitud)
Las entradas son:
+----------+
| sub_str |
+----------+
| texto. |
| ers - 1 |
| ¡Una situación! |
+----------+
NOTA
En Oracle, las expresiones regulares también se pueden
utilizar para extraer una subcadena de utilizando
REGEXP_SUBSTR. Más detalles en la sección de expresiones
r e g u l a r e s en Oracle.
Funciones de cadena |
207
| Y algunos números - 1 2 3 4 5 |
| Y algunos signos de puntuación. :) |
+------------------------------+
Sustituye la palabra algunos por la palabra los:
SELECT REPLACE(mi_texto, 'algunos', 'los')
AS new_text
FROM mi_tabla;
+-----------------------------+
| nuevo_texto |
+-----------------------------+
| Este es el texto. |
| Y los números - 1 2 3 4 5 |
| ¡Y la puntuación! :) |
+-----------------------------+
NOTA
En Oracle y PostgreSQL, las expresiones regulares también
pueden utilizarse para reemplazar una cadena utilizando
REGEXP_REPLACE. Encontrará más detalles en las secciones
Expresiones regulares en Oracle y Expresiones regulares
en PostgreSQL.
+-------------------------+
| nuevo_texto |
+-------------------------+
| Aquí está el texto. |
Funciones de cadena |
209
Hay que tener en cuenta un par de cosas sobre las expresiones
regulares:
CONSEJO
En lugar de memorizar la sintaxis de las expresiones
regulares, recomiendo encontrar expresiones regulares
existentes y m o d i f i c a r l a s para adaptarlas a sus
necesidades.
Para la expresión regular anterior, busqué "expresión
regular texto después de cadena".
El segundo resultado de la búsqueda en Google me llevó a
(?<=WORD).*$. Utilicé Regex101 para entender cada parte
de la expresión regular, y finalmente sustituí WORD por
cuchara.
Funciones de cadena |
211
+----------------------------+ ----------------+
| Ciudad |
+----------------------------+ ----------------+
+--------------------------+------------+
| Ciudad |
+--------------------------+------------+
| The Blues Brothers Chicago
| Ferris Bueller's Day Off | Chi |
+--------------------------+------------+
Las expresiones regulares de MySQL no distinguen entre mayúsculas
y minúsculas para las cadenas de caracteres ; CHI y Chi se consideran
equivalentes.
Encuentra todas las películas con números en el título:
SELECCIONAR *
DE películas
WHERE title REGEXP '\\\d';
+----------------------------+ ----------------+
| Ciudad |
+----------------------------+ ----------------+
| 10 cosas que odio de ti | Seattle |
| 22 Jump Street | Nueva Orleans |
+----------------------------+ ----------------+
En MySQL, cualquier barra invertida simple en una expresión
regular (\d = cualquier dígito) debe cambiarse por una barra
invertida doble.
Funciones de cadena |
213
• REGEXP_LIKE coincide con un patrón de expresión regular
dentro del texto.
• REGEXP_COUNT cuenta el número de veces que aparece un
patrón en el texto.
• REGEXP_INSTR localiza las posiciones en las que aparece un
patrón en el texto.
• REGEXP_SUBSTR devuelve las subcadenas del texto que
coinciden con un patrón.
• REGEXP_REPLACE sustituye las subcadenas que coinciden con
un patrón por otro texto.
TÍTULO CIUDAD
---------------------------- -------------
10 cosas que odio de ti Seattle
22 Jump StreetNueva Orleans
TÍTULO NUM_CAPS
---------------------------- ----------
10 cosas que odio de ti 5
22 Jump Street 2
Los Blues Brothers 3
Ferris Bueller's Day Off 4
Funciones de cadena |
215
WHERE REGEXP_SUBSTR(title, '[0-9]+') IS NOT NULL;
TÍTULO NÚMEROS
---------------------------- ------
10 cosas que odio de ti 10
22 Jump Street 22
Sustituye todos los números del título por el número 100:
SELECT REGEXP_REPLACE(título, '[0-9]+', '100')
AS one_hundred_title
FROM películas;
ONE_HUNDRED_TITLE
-----------------------------
100 cosas que odio de ti
100 Jump Street
NOTA
Puede encontrar más detalles y ejemplos sobre
expresiones regulares en Ora- cle en Oracle Regular
Expressions Pocket Reference de Jonathan Gennick y Peter
Linsley (O'Reilly).
título| ciudad
--------------------------+---------
The Blues Brothers Chicago
Ferris Bueller's Day Off | Chi
Las expresiones regulares de PostgreSQL distinguen entre
mayúsculas y minúsculas para las cadenas de caracteres ter; CHI
y Chi se consideran valores diferentes.
SIMILAR A Versus ~
SIMILAR A ofrece capacidades limitadas de expresión regular, y
se utiliza más a menudo para ofrecer múltiples alternativas
(Chicago|CHI| Chi). Otros símbolos regex comunes para
utilizar con SIMILAR A son
* (0 o más), + (1 o más) y {} (número exacto de veces).
La tilde (~) debe usarse para expresiones regulares más
avanzadas junto con la sintaxis POSIX, que es otro tipo de
expresión regular que soporta PostgreSQL.
La lista completa de símbolos compatibles se encuentra en la
documentación de Post- greSQL.
números en el título:
SELECCIONAR *
DE películas
WHERE title ~ '\d';
+----------------------------+ ----------------+
| Ciudad |
+----------------------------+ ----------------+
| 10 cosas que odio de ti | Seattle |
| 22 Jump Street | Nueva Orleans |
Funciones de cadena |
217
+----------------------------+ ----------------+
regexp_replace
-----------------------------
100 cosas que odio de ti
100 Jump Street
The Blues Brothers
Ferris Bueller's Day Off
La expresión regular \d es equivalente a [0-9] y
[[:dígito::]].
Funciones de cadena |
219
título ciudad
---------------------------- -------------
10 cosas que odio de ti Seattle
22 Jump StreetNueva Orleans
-- Resultados
PostgreSQL Error
En PostgreSQL, debe convertir explícitamente la columna
numérica en una columna de cadena:
len_num
---------
4
3
5
NOTA
El uso de CAST no cambia permanentemente el tipo de
datos de la columna, sólo mientras dure la consulta. Para
cambiar permanentemente el tipo de datos de una
columna, puede modificar la tabla.
-- Oracle
SELECT FECHA_ACtual FROM dual;
SELECT CAST(CURRENT_TIMESTAMP AS TIME) FROM dual;
SELECT CURRENT_TIMESTAMP FROM dual;
-- SQL Server
Funciones de cadena |
221
SELECT CAST(ACTUAL_TIMESTAMP AS DATE);
SELECT CAST(ACTUAL_TIMESTAMP AS TIME);
SELECT ACTUAL_TIMESTAMP;
Existen muchas otras funciones equivalentes a éstas, entre ellas
CURDATE() en MySQL, GETDATE() en SQL Server, etc.
+--------------+
| current_time |
+--------------+
| 20:53:35 |
+--------------+
Crear una tabla que marque la fecha y hora de creación:
CREATE TABLE mi_tabla
(id INT,
creation_datetime TIMESTAMP DEFAULT
HORA_ACTUAL);
+------+ ---------------------+
| id| creation_datetime |
+------+ ---------------------+
|1 | 2021-02-15 20:57:12 |
|2 | 2021-02-15 20:57:12 |
|3 | 2021-02-15 20:57:12 |
+------+ ---------------------+
Buscar todas las filas de datos anteriores a una fecha determinada:
SELECCIONAR *
DESDE mi_tabla
WHERE creation_datetime < CURRENT_DATE;
-- PostgreSQL
diferencia_diaria
---------------------
4 años 1 mes 1 día
2 años 1 mes 1 día
diferencia_tiempo
-----------
3600
1933
-- Oracle
HOUR_DIFF
---------------------------
+000001493 01:00:00.000000
+000000763 00:32:13.000000
-- PostgreSQL
diferencia_horas
------------------------------
4 años 1 mes 1 día 01:00:00
2 años 1 mes 1 día 00:32:13
edad
------------------------------
4 años 1 mes 1 día 01:00:00
2 años 1 mes 1 día 00:32:13
Utilice la función EXTRACT para extraer sólo el campo del año.
SELECT EXTRACT(año FROM
AGE(fecha_final, fecha_inicial))
FROM mi_tabla;
fecha_parte
-----------
4
2
• Fecha: 2020-03-16
• Día numérico de la semana: 2 (el domingo es el primer día)
• Día de la semana Lunes
Redondeo en Oracle
Oracle permite redondear y truncar una fecha al año, mes o día
más próximo (primer día de la semana).
Para redondear a primeros de mes:
SELECT TRUNC(fecha '2020-02-25', 'mes')
DE doble;
01-FEB-20
Para redondear al mes más próximo:
SELECT ROUND(fecha '2020-02-25', 'mes')
DE doble;
01-MAR-20
Redondeo en PostgreSQL
PostgreSQL permite truncar una fecha al año, trimestre, mes,
semana (primer día de la semana), día, hora, minuto o segundo
más cercano. Puede encontrar unidades de tiempo adicionales
en la documentación de PostgreSQL.
2020-02-01 00:00:00-06
Para redondear al minuto:
SELECT DATE_TRUNC('minuto', TIEMPO '10:30:59.12345');
10:30:00
La función CAST
Si una columna de cadena contiene fechas en un formato
estándar, puede utilizar la función CAST para convertirla en un
tipo de datos de fecha.
La Tabla 7-23 muestra el código para convertir a un tipo de datos de
fecha.
Tabla 7-23. Convertir una cadena en una fecha
RDBMSCódigo de formato de fecha requerido
MySQL, YYYY-MM-DDSELECT
PostgreSQL, CAST('2020-10-15'
SQL Server COMO FECHA);
Oracle DD-MON-AAAA CAST('15-OCT-2020')
COMO FECHA)
DE doble;
SQLite YYYY-MM-DDSELECT DATE('2020-10-
15');
NOTA
SQL Server utiliza la función CONVERT para cambiar una
cadena a un tipo de dato datetime. VARCHAR es el tipo de
datos original, 10-15-22 es la fecha, y 105 representa el
formato MM-DD- YYYY.
Otros formatos de fecha son MM/DD/AAAA (101), AAAA.MM.DD
(102), DD/MM/AAAA (103) y DD.MM.AAAA (104). Más para-
en la documentación de Microsoft.
Los formatos de hora son hh:mi:ss (108) y hh:mi:ss:mmm
(114), ninguno de los cuales coincide con el formato de la
Tabla 7-26, razón por la cual la hora no puede ser leída
por SQL Server utilizando CON VERT.
NOTA
SQLite no dispone de funciones de fecha y hora, pero se
puede utilizar la función SUBSTR (subcadena) para extraer
los cuatro últimos dígitos de .
Funciones nulas
Las funciones nulas pueden aplicarse a cualquier tipo de columna y se
activan en cuando se encuentra un valor nulo.
+----------+
| saludo |
+----------+
| hola |
| ¡Hola! |
| Hola |
+----------+
MySQL y SQLite también aceptan IFNULL(greeting, 'hi').
Oracle también acepta NVL(greeting, 'hola').
SQL Server también acepta ISNULL(greeting, 'hi').
237
SELECT
house_id,
CASE WHEN
flg = 1
ENTONCES
"en venta
ELSE
"vendido"
END
DE las
casas;
SELECCIONE
zip, AVG(ft)
DE casas
GROUP BY
zip;
Casos prácticos
Una sentencia CASE se utiliza para aplicar la lógica if-else dentro
de una consulta. Por ejemplo, puede utilizar una sentencia CASE
para deletrear valores. Si se ve un 1, muestra vip. Si no, muestra
admisión general.
+--------+ +-------------------+
| ticket | | Billete |
+--------+ +-------------------+
|1 | | VIP |
|0 | --> | Entrada general
|1 | | VIP |
+--------+ +-------------------+
239
NOTA
El uso de una sentencia CASE actualiza temporalmente los
valores mientras dura la consulta. Para guardar los valores
actualizados, puede hacerlo con una sentencia UPDATE.
+-------+-------+
| Nombre Bandera
+-------+-------+
| anton |1 |
| julia |0 |
Declaraciones de casos |
239
| maren |1 |
| sarah | NULL |
+-------+-------+
Implementa la lógica if-else con una simple sentencia CASE:
SELECCIONAR nombre, bandera,
CASE flag WHEN 1 THEN 'vip'
WHEN 0 THEN 'asientos
reservados'
ELSE 'general admission' END AS ticket
DE concierto;
+-------+------+ --------------------+
| Nombre Bandera Entrada |
+-------+------+ --------------------+
| anton |1 | vip |
| julia |0 | asientos reservados |
| maren |1 | vip |
| sarah | NULL | admisión general |
+-------+------+ --------------------+
Si no coincide ninguna cláusula WHEN y no se especifica ningún valor
ELSE, se emitirá un
Se devolverá NULL.
+-------+-------+
| Nombre Bandera
+-------+-------+
| anton |1 |
| julia |0 |
| maren |1 |
| sarah | NULL |
+-------+-------+
Implemente la lógica if-else con una sentencia CASE buscada:
SELECCIONAR nombre, bandera,
CASE WHEN name = 'anton' THEN 'vip'
WHEN flag IN (0,1) THEN 'asientos
reservados' ELSE 'admisión general' END AS
ticket
DE concierto;
+-------+------+ --------------------+
| Nombre Bandera Entrada |
+-------+------+ --------------------+
| anton |1 | vip |
| julia |0 | asientos reservados |
| maren |1 | asientos reservados |
| sarah | NULL | admisión general |
+-------+------+ --------------------+
Si se cumplen varias condiciones, prevalece la primera.
NOTA
Para sustituir todos los valores NULL de una columna por
otro valor, podría utilizar una sentencia CASE, pero es más
habitual utilizar la función NULL COALESCE en su lugar.
Declaraciones de casos |
241
Agrupar y resumir
SQL permite separar las filas en grupos y resumir las filas dentro
de cada grupo de alguna manera, devolviendo finalmente sólo
una fila por grupo.
La Tabla 8-2 enumera los conceptos asociados a la agrupación y
suma de datos.
Tabla 8-2. Agrupación y resumen de conceptos
Categoría Palabra clave Descripción
El concepto principal GRUPO POR Utilice la cláusula GROUP BY para
separar las filas de datos en grupos.
Formas de resumir COUNT Estas funciones de agregación
filas dentro de cada SUM resumen varias filas de datos en un
grupo MIN único valor.
MAX
AVG
ARRAY_AGG Estas funciones combinan varias
GROUP_CONCAT filas de datos en una sola lista.
LISTAGG
STRING_AGG
Ampliaciones de la ROLLUP Incluye filas para subtotales y también el total
Cláusula GROUP general.
BY
CUBO Incluye agregaciones para
todas las combinaciones
posibles de las columnas
agrupadas por.
CONJUNTO Permite especificar las
S DE agrupaciones concretas que se
AGRUPACI mostrarán.
ÓN
Conceptos básicos de
GROUP BY
La siguiente tabla muestra el número de calorías quemadas por
Declaraciones de casos |
243
+------+ ----------+
| nombre | calorías |
+------+ ----------+
| ally |80 |
| ...aliado... 75...
| ally |90 |
| jess |100 |
| jess |92 |
+------+ ----------+
Para crear un cuadro resumen, tienes que decidir cómo hacerlo:
+------+ ----------------+
| name | total_calories |
+------+ ----------------+
| ally |245 |
| ...jess... 192...
+------+ ----------------+
Encontrará más detalles sobre cómo funciona GROUP BY entre
bastidores en la sección La cláusula GROUP BY del capítulo 4.
+------+------+----------+-------------+
| id| nombre | entrenamientos | calorías |
+------+------+----------+-------------+
|1 | aliado |3 |245 |
|2 | jess |2 |192 |
+------+------+----------+-------------+
+------+ ----------+
| nombre | calorías |
+------+ ----------+
| ally |80 |
| ...aliado... 75...
| ally |90 |
+------+ ---------------+
| nombre | calories_list |
+------+ ---------------+
| ally | 80,75,90 |
| jess | 100,92 |
+------+ ---------------+
La función GROUP_CONCAT difiere para cada RDBMS. La Tabla 8-
3 muestra la sintaxis soportada por cada RDBMS:
Tabla 8-3. Agregar filas en una lista en cada RDBMS
RDBMS Separador CodeDefault
MySQL GROUP_CONCAT(calorías) Coma
GROUP_CONCAT(calorías
SEPARADOR ',')
Oracle LISTAGG(calorías) Sin valor
LISTAGG(calorías, ',')
PostgreSQL ARRAY_AGG(calorías) Coma
SQL Server STRING_AGG(calorías, ',') Separador obligatorio
SQLite GROUP_CONCAT(calorías) Coma
GROUP_CONCAT(calorías, ',')
ROLLUP
MySQL, Oracle, PostgreSQL y SQL Server soportan ROLLUP, que
amplía el GROUP BY incluyendo filas adicionales para subtotales y
el total general.
Utilice ROLLUP para visualizar t a m b i é n los gastos anuales y
totales. Las líneas de gastos de 2019, 2020 y total se añaden con la
adición de ROLLUP:
SELECCIONE año, mes,
SUM(importe) AS total
FROM gastos
GROUP BY ROLLUP(año, mes)
ORDER BY año, mes;
CONJUNTOS DE AGRUPACIÓN
Oracle, PostgreSQL y SQL Server admiten CONJUNTOS DE
AGRUPACIÓN, que permiten especificar agrupaciones concretas
que se desean mostrar en .
Estos datos son un subconjunto de los resultados generados por
CUBE, que sólo incluyen agrupaciones de una columna cada vez.
En este caso, sólo se muestran los gastos totales anuales y
mensuales:
Funciones de ventana
Una función ventana (o función analítica en Oracle) es similar a
una función agregada en el sentido de que ambas realizan un
cálculo sobre filas de datos. La diferencia es que una función
agregada devuelve un único valor, mientras que una función
ventana devuelve un valor por cada fila de datos.
La siguiente tabla muestra una lista de empleados con sus ventas
mensuales. Las siguientes consultas utilizan esta tabla para
mostrar la diferencia entre una función agregada y una función
de ventana.
SELECT * FROM ventas;
+-------+-------+ --------+
| Nombre Mes Ventas
+-------+-------+ --------+
| David | 3 | 2 |
| David | 4 | 11 |
| Laura | 3 | 3 |
| Laura | 4 | 14 |
| Laura | 5 | 7 |
| Laura | 6 | 1 |
+-------+-------+ --------+
+-------+--------------+
| nombre | total_ventas |
+-------+--------------+
| David |13 |
| Laura |25 |
+-------+--------------+
Función de ventana
ROW_NUMBER() OVER (PARTITION BY name ORDER BY month) es un
función de ventana. En la parte en negrita de la siguiente
consulta, para cada persona se genera un número de fila que
representa el primer mes, el segundo mes, etc. en que vendió
algo. La consulta devuelve cada fila junto con su valor
sale_month.
SELECCIONAR nombre,
ROW_NUMBER() OVER (PARTITION BY name
ORDER BY month) AS sale_month
FROM sales;
+-------+-------------+
| nombre | venta_mes |
+-------+-------------+
| David |1 |
| David |2 |
| Laura |1 |
| Laura |2 |
| Laura |3 |
| Laura |4 |
+-------+-------------+
+--------+--------+--------------+
| género nombre popularidad
+--------+--------+--------------+
| M | Noah | 1 |
| M | Liam | 2 |
| F | Olivia | 3 |
| M | Mateo | 4 |
| F | Emma | 5 |
| F | Mia | 6 |
+--------+--------+--------------+
Ordena los nombres por popularidad para cada sexo:
SELECCIONAR sexo, nombre,
ROW_NUMBER() OVER (PARTITION BY gender
ORDER BY babies DESC) AS popularity
FROM baby_names;
+--------+--------+--------------+
+--------+--------+--------+ ---------------+
| Género Nombre | bebés top_name
+--------+--------+--------+ ---------------+
| F | Olivia | 100 | Olivia |
| F | Emma | 92 | Olivia |
| F | Mia | 88 | Olivia |
| M | Noah | 110 | Noah |
| M | Liam | 105 | Noah |
| M | Mateo | 95 | Noah |
+--------+--------+--------+ ---------------+
+--------+--------+--------+ ---------------+
| Género Nombre | bebés top_name
+--------+--------+--------+ ---------------+
|F | Olivia 100 Olivia |
+--------+--------+--------+ ------------------+
| Género Nombre | bebés segundo nombre
+--------+--------+--------+ ------------------+
| F | Olivia | 100 | NULL |
| F | Emma | 92 | Emma |
| F | Mia | 88 | Emma |
| M | Noah | 110 | NULL |
| M | Liam | 105 | Liam |
| M | Mateo | 95 | Liam |
+--------+--------+--------+ ------------------+
+--------+--------+--------+ ------------------+
| Género Nombre | bebés segundo nombre
+--------+--------+--------+ ------------------+
|F | Emma | 92 Emma |
|M | Liam | 105 Liam |
+--------+--------+--------+ ------------------+
+--------+--------+--------+ -----------------+
| Género y nombre | bebés popularidad
+--------+--------+--------+ -----------------+
| F | Olivia | 100 | 1 |
| F | Emma | 92 | 2 |
| F | Mia | 88 | 3 |
| M | Noah | 110 | 1 |
| M | Liam | 105 | 2 |
| M | Mateo | 95 | 3 |
+--------+--------+--------+ -----------------+
+--------+--------+--------+ -----------------+
| Género y nombre | bebés popularidad
+--------+--------+--------+ -----------------+
|F | Olivia 100 | 1 |
|F | Emma | 92 | 2 |
|M | Noah | 110 | 1 |
|M | Liam | 105 | 2 |
+--------+--------+--------+ -----------------+
+--------+--------+--------+---------------+
| sexo nombre bebés nombre anterior
+--------+--------+--------+---------------+
| F | Olivia | 100 | NULL |
| F | Emma | 92 | Olivia |
| F | Mia | 88 | Emma |
| M | Noah | 110 | NULL |
| M | Liam | 105 | Noah |
| M | Mateo | 95 | Liam |
+--------+--------+--------+---------------+
+--------+--------+--------+-----------------+
| género | nombre| bebés | nombre_anterior_2 |
+--------+--------+--------+-----------------+
| F | Olivia | 100 | Sin nombre |
| F | Emma | 92 | Sin nombre |
| F | Mia | 88 | Olivia |
| M | Noah | 110 | Sin nombre |
| M | Liam | 105 | Sin nombre |
| M | Mateo | 95 | Noah |
+--------+--------+--------+-----------------+
Las funciones LAG y LEAD reciben tres argumentos cada una:
LAG(nombre, 2, 'Ninguno')
+-------+-------+-------+ ------------------+
| nombre | mes | ventas | tres_meses_ma |
+-------+-------+-------+ ------------------+
| David | 1 | 2 | 2.0000 |
| David | 2 | 11 | 6.5000 |
| David | 3 | 6 | 6.3333 |
| David | 4 | 8 | 8.3333 |
| Laura | 1 | 3 | 3.0000 |
| Laura | 2 | 14 | 8.5000 |
| Laura | 3 | 7 | 8.0000 |
| Laura | 4 | 1 | 7.3333 |
| Laura | 5 | 20 | 9.3333 |
+-------+-------+-------+ ------------------+
Calcular el total
Utilice una combinación de la función SUM y la cláusula ROWS BETWEEN
UNBOUNDED para calcular el total acumulado.
+-------+-------+-------+ -----------------+
| nombre mes ventas total actual
+-------+-------+-------+ -----------------+
| David | 1 | 2 | 2 |
| David | 2 | 11 | 13 |
| David | 3 | 6 | 19 |
| David | 4 | 8 | 27 |
| Laura | 1 | 3 | 3 |
| Laura | 2 | 14 | 17 |
| Laura | 3 | 7 | 24 |
| Laura | 4 | 1 | 25 |
| Laura | 5 | 20 | 45 |
+-------+-------+-------+ -----------------+
+-------+-------+----------+-----------------+
| mes | nombre | rt_rows | rt_range |
+-------+-------+----------+-----------------+
| 1 | David | 2| 5|
| 1 | Laura | 5| 5|
| 2 | David | 16 | 30 |
| 2 | Laura | 30 | 30 |
| 3 | David | 36 | 43 |
| 3 | Laura | 43 | 43 |
| 4 | David | 51 | 52 |
| 4 | Laura | 52 | 52 |
| 5 | Laura | 72 | 72 |
+-------+-------+----------+-----------------+
+------+-------+ ---------------+
| id| nombre | fruta |
+------+-------+ ---------------+
|1 | Henry | fresas |
|2 | Henry | pomelo |
|3 | Henry | sandía |
|4 | Lirio | fresas |
|5 | Lirio | Sandía |
|6 | Lirio | fresas |
|7 | Lirio | sandía |
+------+-------+ ---------------+
Resultado esperado:
+-------+--------------+------------+ ----------------+
| nombre | fresas | pomelo | sandía |
+-------+--------------+------------+ ----------------+
| Henry |1 |1 |1 |
| Lily |2 |0 |2 |
+-------+--------------+------------+ ----------------+
Utilice la operación PIVOT en Oracle y SQL Server:
-- SQL Server
SELECT *
DE frutas
PIVOT
(COUNT(id) FOR fruta IN ([fresas],
[pomelo], [sandía])
) AS frutas_pivot;
En la sección PIVOT, se hace referencia a las columnas id y
fruta, pero no a la columna nombre. Por lo tanto, la columna de
nombre permanecerá como su propia columna en el resultado
final y cada fruta se convertirá en una nueva columna.
Los valores de la tabla son el recuento del número de filas de la
tabla original que contenían cada combinación concreta de
nombre y fruta.
+----+-------+-----------+-----------+ ---------------+
| id | name | fruit_one | fruit_two | fruit_thr |
+----+-------+-----------+-----------+ ---------------+
| 1 | Anna | manzana| plátano |
|
| 2 | Barry | frambuesa | | |
| 3 | Liz| limón| lima| naranja |
| 4 | Tom| melocotón| pera| ciruela |
+----+-------+-----------+-----------+ ---------------+
Resultado esperado:
+----+-------+-----------+---------+
| id | nombre | fruta| rango |
+----+-------+-----------+---------+
| 1 | Anna | manzana | 1 |
| 1 | Anna | plátano | 2 |
| 2 | Barry | frambuesa | 1 |
| 3 | Liz | limón | 1 |
| 3 | Liz | lima | 2 |
| 3 | Liz | naranja | 3 |
| 4 | Tom | melocotón | 1 |
| 4 | Tom | pera | 2 |
| 4 | Tom | ciruela | 3 |
+----+-------+-----------+---------+
Utilice la operación UNPIVOT en Oracle y SQL Server:
-- Oracle
SELECT *
FROM frutas_favoritas
UNPIVOT
-- SQL Server
SELECT *
FROM frutas_favoritas
UNPIVOT
(fruta FOR rango IN (fruta_uno,
fruta_dos,
fruta_thr)
) AS fruit_unpivot
WHERE fruit <> '';
La sección UNPIVOT toma las columnas fruit_one, fruit_two y
fruit_thr y las consolida en una sola columna llamada fruit.
Una vez hecho esto, puede seguir adelante y utilizar una
sentencia SELECT típica para extraer las columnas id y name
originales junto con la columna fruit recién creada.
269
Concepto DescripciónCódigo Ejemplo
Expresiones Guarda temporalmente WITH mi_cte AS (
comunes la salida de una consulta, SELECT nombre,
SUM(pedido_id
de tabla para que otra consulta
) COMO
haga referencia a ella. numero_pedido
También incluye s
consultas FROM clientes
recursivas y jerárquicas. GROUP BY nombre)
SELECT MAX(num_orders)
FROM mi_cte;
Unir tablas
En SQL, unir significa combinar datos de varias tablas en una
sola consulta. Las dos tablas siguientes muestran el estado en el
que vive una persona y las mascotas que posee:
-- estados-- mascotas
+------+-------++------+ ------------+
| nombre | estado || nombre | mascota |
+------+-------++------+ ------------+
| Ada, AZ || Deb, perro
| Deb | DE || Deb, Pato.
+------+-------+| Pat | cerdo |
+------+ ------+
Utilice la cláusula JOIN para unir las dos tablas en una sola:
SELECCIONAR *
FROM estados s INNER JOIN mascotas p
ON s.name = p.name;
+------+-------+------+ --------+
| nombre | estado | nombre | mascota |
+------+-------+------+ --------+
| Deb | DE| Deb | dog |
| Deb | DE| Deb | pato |
+------+-------+------+ --------+
La tabla resultante sólo incluye filas para Deb, ya que está
presente en ambas tablas.
Además del INNER JOIN, la Tabla 9-2 enumera los distintos tipos
de uniones en SQL. La siguiente consulta muestra el formato
general para unir tablas:
SELECCIONAR *
FROM estados s [JOIN_TYPE]
mascotas p ON s.name =
p.name;
Sustituya la parte en negrita [JOIN_TYPE] por las palabras clave
de l a columna Keyword para obtener los resultados que se
muestran en la columna Resulting Rows. Para el tipo de unión
Unir tablas | 271
CROSS JOIN, excluya la cláusula ON para obtener los resultados
mostrados en la tabla.
SELECCIONAR *
DE estados s1
INNER JOIN
estados s2
WHERE s1.region
= s2.region;
Fundamentos de la adhesión
Puede pensar en unir tablas en dos pasos:
+------+-------+------+----------+
| nombre | estado | nombre | mascota |
+------+-------+------+----------+
| Ada, AZ | Deb, perro
| Deb, DE | Deb | perro |
| Ada, AZ | Deb | pato |
| Deb, DE | Deb | pato |
| Ada, AZ | Pat | cerdo |
| Deb, DE | Pat | cerdo |
+------+-------+------+----------+
+------+-------+------+----------+
| nombre | estado | nombre | mascota |
+------+-------+------+----------+
| Deb, DE | Deb | perro |
| Deb, DE | Deb | pato |
+------+-------+------+----------+
La línea Deb/DE aparece dos veces porque coincide con dos Deb
en la tabla de mascotas.
El código anterior es equivalente a un INNER JOIN.
INNER JOIN
La forma más habitual de unir dos tablas es mediante una tabla
INNER JOIN, que devuelve las filas que están en ambas tablas.
Utilice INNER JOIN para devolver sólo las personas de ambas tablas
SELECCIONAR *
FROM estados s INNER JOIN mascotas p
ON s.name = p.name;
+------+-------+------+----------+
| nombre | estado | nombre | mascota |
+------+-------+------+----------+
| Deb, DE | Deb | perro |
| Deb, DE | Deb | pato |
+------+-------+------+----------+
+------+-------+------+------+------+ ------------+
| nombre | estado | edad | nombre | mascota | edad |
+------+-------+------+------+------+ ------------+
| Ada AZ | 30 | Ada | ant | 30 |
+------+-------+------+------+------+ ------------+
LEFT JOIN
Utilice LEFT JOIN para devolver todas las personas de la tabla
states. Las personas de la tabla de estados que no están en la
tabla de mascotas se devuelven con valores NULL.
SELECCIONAR *
FROM estados s LEFT JOIN
mascotas p ON s.nombre =
p.nombre;
+------+-------+------+ --------+
| nombre | estado | nombre | mascota |
+------+-------+------+ --------+
Unir tablas | 279
| Ada | AZ| NULL | NULL |
| Deb | DE| Deb | dog |
| Deb | DE| Deb | pato |
+------+-------+------+ --------+
Una LEFT JOIN es equivalente a una LEFT OUTER JOIN.
UNIÓN A LA DERECHA
Utilice RIGHT JOIN para devolver todas las personas de la tabla
pets. Las personas de la tabla de mascotas que no están en la
tabla de estados se devuelven con valores NULL.
SELECCIONAR *
FROM estados s RIGHT JOIN
mascotas p ON s.nombre =
p.nombre;
+------+-------+------+ --------+
| nombre | estado | nombre | mascota |
+------+-------+------+ --------+
| Deb | DE| Deb | dog |
| Deb | DE| Deb | pato |
| NULL | NULL | Pat | cerdo |
+------+-------+------+ --------+
Una RIGHT JOIN es equivalente a una RIGHT OUTER JOIN.
SQLite no soporta RIGHT JOIN.
CONSEJO
El LEFT JOIN es mucho más común que el RIGHT JOIN. Si
necesita una RIGHT JOIN, intercambie las dos tablas en la
cláusula FROM y realice una LEFT JOIN en su lugar.
+------+-------+------+ --------+
| nombre | estado | nombre | mascota |
+------+-------+------+ --------+
| Ada | AZ| NULL | NULL |
| Deb | DE| Deb | dog |
| Deb | DE| Deb | pato |
| NULL | NULL | Pat | cerdo |
+------+-------+------+ --------+
Un FULL OUTER JOIN es equivalente a un FULL JOIN.
MySQL y SQLite no soportan FULL OUTER JOIN.
USO DE
MySQL, Oracle, PostgreSQL y SQLite admiten la función USING
cláusula.
Puede utilizar el método abreviado USING en lugar de la cláusula
ON para unir en dos columnas con el mismo nombre. La unión
debe ser una unión equitativa (= en la cláusula ON) para utilizar
USING.
-- Cláusula ON
SELECT *
FROM estados s INNER JOIN mascotas p
ON s.name = p.name;
+------+-------+------+ --------+
| nombre | estado | nombre | mascota |
+------+-------+------+ --------+
| Deb | DE| Deb | dog |
+------+-------+ -------+
| nombre | estado | mascota |
+------+-------+ -------+
| Deb | DE| dog |
| Deb | DE| pato |
+------+-------+ -------+
La diferencia entre las dos consultas es que la primera devuelve
cuatro columnas, incluyendo s.name y p.name, mientras que la
segunda devuelve tres columnas porque las dos columnas de nombre
se fusionan en una sola y se llama simplemente nombre.
UNIÓN NATURAL
MySQL, Oracle, PostgreSQL y SQLite soportan NATURAL JOIN.
Puede utilizar el método abreviado NATURAL JOIN en lugar de la
sintaxis INNER JOIN .. ON .. para unir dos tablas basándose en
todas las columnas de que tengan exactamente el mismo
nombre. La unión debe ser equi-join (= en la cláusula ON) para
utilizar NATURAL JOIN.
-- INNER JOIN ... ON ... Y ... SELECT
*
FROM states_ages s INNER JOIN pets_ages p
ON s.name = p.name
AND s.age = p.age;
+------+-------+------+------+------+ ----------+
| nombre | estado | edad | nombre | mascota |
edad |
+------+-------+------+------+------+ ----------+
| Ada | AZ |30 | Ada | ant |30 |
+------+-------+------+------+------+ ----------+
+------+------+-------+ --------+
| Nombre Edad Estado Mascota
+------+------+-------+ --------+
| Ada |30 | AZ| ant |
+------+------+-------+ --------+
La diferencia entre las dos consultas es que la primera devuelve
seis columnas, incluyendo s.nombre, s.edad, p.nombre y p.edad,
mientras que la segunda devuelve cuatro columnas porque las
columnas duplicadas de nombre y edad se fusionan y se llaman
simplemente nombre y edad.
ADVERTENCIA
Tenga cuidado al utilizar un NATURAL JOIN. Ahorra un
poco de escritura, pero puede hacer una unión inesperada
si se añade o elimina de una tabla una columna con el
mismo nombre. Es mejor utilizarlo para consultas rápidas
que para código de producción.
CROSS JOIN
Utilice CROSS JOIN para devolver todas las combinaciones de las
filas de dos tablas. Equivale a enumerar las tablas en la cláusula
FROM (lo que a veces se denomina "sintaxis join antigua").
-- CROSS JOIN
SELECT *
-- Lista de tablas
equivalente SELECT *
DE estados, mascotas;
+------+-------+------+ --------+
| nombre | estado | nombre | mascota |
+------+-------+------+ --------+
| Ada | AZ | Deb | perro |
| Deb | DE | Deb | perro |
| Ada | AZ | Deb | pato |
| Deb | DE | Deb | pato |
| Ada | AZ | Pat | cerdo |
| Deb | DE | Pat | cerdo |
+------+-------+------+ --------+
Una vez l i s t a d a s todas las combinaciones, puede optar por
filtrar los resultados añadiendo una cláusula WHERE para devolver
menos filas en función de lo que esté buscando.
+------+--------+----------+-----------+
| dept | emp_id | emp_name | mgr_id |
+------+--------+----------+-----------+
+----------+ ------------+
| emp_name | mgr_name |
+----------+ ------------+
| Nancy | Lisa |
| Olivia | Lisa |
| Penny | Monica |
+----------+ ------------+
+------+----------+ -------------+
| dept | emp_name | emp_name |
+------+----------+ -------------+
| tech | monica | Lisa |
| tech | lisa | Monica |
| data | penny | nancy |
| Olivia | Nancy |
| Datos | Olivia |
| Datos Nancy | Olivia |
| Datos Olivia | penny |
| data | nancy | penny |
+------+----------+ -------------+
Operarios sindicales
Utilice la palabra clave UNION para combinar los resultados de
dos o más sentencias SELECT de . La diferencia entre JOIN y
UNION es que JOIN une varias tablas en una sola consulta,
mientras que UNION apila los resultados de varias consultas:
-- JOIN ejemplo
SELECT *
FROM cumpleaños b JOIN velas c
ON b.nombre = c.nombre;
-- UNION ejemplo
SELECT * FROM
escritores UNION
SELECT * FROM artistas;
La figura 9-1 muestra la diferencia entre los resultados de un JOIN
y una UNION, basada en el código anterior.
UNIÓN
La palabra clave UNION combina los resultados de dos o más SELECT
en una sola salida.
-- residentes
+---------+---------+ --------------+
| Nombre País Ocupación
+---------+---------+ --------------+
| eleanor usa temp |
| chidi| nigeria | profesor |
| tahani | inglaterra | modelo|
| jason usa dj |
+---------+---------+ --------------+
Utilice UNION para combinar las dos tablas y eliminar las filas
duplica d a s :
SELECT nombre, origen FROM personal
UNIÓN
SELECT nombre, país FROM residentes;
+---------+----------+
| Nombre Origen
+---------+----------+
| michael | NULL |
| NULL |
| tahani | inglaterra |
| eleanor | usa |
| chidi nigeria
| jason usa |
+---------+----------+
Tenga en cuenta que tahani/england aparece tanto en la plantilla
como en
residentes. Sin embargo, sólo aparece como una fila en la tabla
UNIÓN TODOS
Utilice UNION ALL para combinar las dos tablas y conservar las
filas duplicadas:
SELECT nombre, origen FROM personal
UNIÓN TODOS
SELECT nombre, país FROM residentes;
+---------+----------+
| Nombre Origen
+---------+----------+
| michael | NULL |
| NULL |
| tahani | inglaterra |
| eleanor | usa |
| chidi nigeria
CONSEJO
Si sabe con certeza que no h a y filas duplicadas, utilice
UNION ALL para mejorar el rendimiento. UNION realiza
una ordenación adicional entre bastidores para identificar
los duplicados.
Filtra los valores nulos y ordena los resultados de una consulta UNION:
SELECT nombre, origen
FROM personal
WHERE origen IS NOT NULL
UNIÓN
ORDER BY nombre;
+---------+----------+
| Nombre Origen
+---------+----------+
| chidi nigeria
| eleanor | usa |
| jason usa |
| tahani | inglaterra |
+---------+----------+
UNIÓN
UNIÓN
CONSEJO
UNION se utiliza normalmente para combinar resultados
de varias tablas. Si va a combinar resultados de una sola
tabla, es mejor que escriba una sola consulta y utilice la
cláusula WHERE, la sentencia CASE, etc. adecuadas.
EXCEPTO e INTERSECCIÓN
Además de utilizar UNION para combinar las filas de varias tablas,
puede utilizar EXCEPT e INTERSECT para combinar las filas de
diferentes maneras.
EXCEPTO
Utilice EXCEPT para "sustraer" los resultados de una consulta de
otra consulta.
Devolver a los miembros del personal que no sean residentes:
+---------+
| Nombre |
+---------+
| michael |
| Janet |
+---------+
MySQL no soporta EXCEPT. En su lugar, puede utilizar las
palabras clave NOT IN como solución:
SELECT nombre
FROM personal
WHERE name NOT IN (SELECT name FROM residents);
Oracle utiliza MINUS en lugar de EXCEPT.
PostgreSQL también admite EXCEPT ALL, que no elimina
duplicados. EXCEPT elimina todas las apariciones de un valor,
mientras que EXCEPT ALL elimina instancias específicas.
INTERSECT
Utilice INTERSECT para encontrar las filas en común entre dos
consultas .
Devuelve también a los miembros del personal que son residentes:
SELECT nombre, origen FROM personal
INTERSECT
SELECT nombre, país FROM residentes;
+---------+----------+
| Nombre Origen
+---------+----------+
| tahani | inglaterra |
+---------+----------+
MySQL no soporta INTERSECT. En su lugar, puede utilizar un
INNER JOIN como solución:
SELECCIONAR *
FROM mi_cte
WHERE avg_grade < 70;
He aquí un ejemplo de CTE recursiva en la práctica:
-- Generar los números del 1 al 10
WITH RECURSIVE mi_cte(n) AS
(
SELECT 1 -- Incluir FROM dual en Oracle
UNION ALL
SELECT n + 1 FROM mi_cte WHERE n < 10
)
+-------+--------------+
| dept | avg_salary |
+-------+--------------+
|. 78000 |
| Ventas 61000 |
| Tecnología 83000 |
+-------+--------------+
-- Enfoque CTE
WITH avg_dept_salary AS (
SELECT dept, AVG(salary) AS avg_salary
FROM empleados
GROUP BY dept)
SELECCIONAR *
FROM avg_dept_salary
ORDER BY avg_salary DESC
LIMIT 1;
+------+ -------------+
| dept | avg_salary |
+------+ -------------+
| Tecnología 83000 |
+------+ -------------+
SELECCIONAR *
CTE recursivos
Esta sección recorre dos situaciones prácticas en las que sería útil
un CTE recursivo .
+------------+ ---------+
| Fecha Precio
+------------+ ---------+
| 2021-03-01 | 668.27 |
| 2021-03-03 | 678.83 |
| 2021-03-04 | 635.40 |
| 2021-03-06 | 591.01 |
+------------+ ---------+
Rellene las fechas con un proceso de dos pasos:
+ ------------+
| dt |
+ ------------+
| 2021-03-01 |
| 2021-03-02 |
| 2021-03-03 |
| 2021-03-04 |
| 2021-03-05 |
| 2021-03-06 |
+ ------------+
-- Sintaxis MySQL
WITH RECURSIVE mis_fechas(dt) AS (
SELECT '2021-03-01'
UNIÓN TODOS
SELECT dt + INTERVALO 1 DÍA
FROM mis_fechas
WHERE dt < '2021-03-06')
+------------+ ----------+
| dt | Precio
+------------+ ----------+
| 2021-03-01 | 668.27 |
| 2021-03-02 | NULL
| 2021-03-03 | 678.83 |
| 2021-03-04 | 635.40 |
| 2021-03-05 | NULL
| 2021-03-06 | 591.01 |
+------------+ ----------+
Paso 3 (Opcional): Rellene los valores nulos con el precio del día
anterior.
Sustituya la cláusula SELECT (SELECT d.dt, s.price) por:
SELECT d.dt, COALESCE(s.precio,
LAG(s.precio) OVER
(ORDER BY d.dt)) COMO precio
...
+------------+ ----------+
| dt | Precio
+------------+ ----------+
| 2021-03-01 | 668.27 |
| 2021-03-02 | 668.27 |
| 2021-03-03 | 678.83 |
| 2021-03-04 | 635.40 |
| 2021-03-05 | 635.40 |
| 2021-03-06 | 591.01 |
+------------+ ----------+
+------+---------+----------+ --------------+
| id| name| role| parent_id |
+------+---------+----------+ --------------+
|1 | Lao Ye | Abuelo |NULL |
|2 | Lao Lao | Abuela |NULL |
NOTA
El siguiente código se ejecuta en MySQL. La Tabla 9-5
contiene la sintaxis para cada RDBMS.
+------+---------+---------------------------+
| id| nombre| linaje |
+------+---------+---------------------------+
| 1 | Lao Ye | Lao Ye |
| 2 | Lao Lao | Lao Lao |
| 3 | Ollie | Ollie |
| 4 | Alice | Lao Ye > Alice |
| 4 | Alice | Lao Lao > Alice |
+----+--------+ --------------+
| id | té| temperatura |
303
+----+--------+ --------------+
| 1 Verde 170
| 2 negro 200 |
+--------+--------------+
| Temperatura
+--------+--------------+
| verde |170 |
| negro | 200 |
| hierbas 212 |
| ...a base de hierbas... 210...
| oolong |185 |
+--------+--------------+
Posibles ampliaciones
Para obtener el número de filas únicas de una tabla, utilice las
palabras clave COUNT y DISTINCT a la vez. Encontrará más
información en la sección DISTINCT del capítulo 4.
305
Devolver sólo las filas con valores duplicados
La siguiente consulta identifica las filas de la tabla con valores
duplicados.
WITH dup_rows AS (
SELECT té, temperatura,
COUNT(*) as num_rows
DE tés
GROUP BY té, temperatura
TENIENDO COUNT(*) > 1)
+----+--------+ --------------+
| id | té| temperatura |
+----+--------+ --------------+
| 2 | negro |200 |
| 3 | negro |200 |
| 4 | herbal |212 |
| 5 | herbal |212 |
+----+--------+ --------------+
Explicación
La mayor parte del trabajo se realiza en la consulta dup_rows. Se
cuentan todas las combinaciones de té y temperatura y, a
continuación, sólo se conservan las combinaciones que aparecen
más de una vez con la cláusula HAVING de . Este es el aspecto de
dup_rows:
+--------+-------------+ ------------+
| té| temperatura | num_rows |
+--------+-------------+ ------------+
| negro |200 |2 |
| herbal |212 |2 |
+--------+-------------+ ------------+
El propósito del JOIN en la segunda mitad de la consulta es
volver a introducir la columna id en la salida final.
Posibles ampliaciones
Para eliminar determinadas filas duplicadas de una tabla, utilice un
DELETE
declaración. Encontrará más información en el capítulo 5
+------+----------+------------+ ----------+
| id| empleado | fecha| ventas |
+------+----------+------------+ ----------+
| 1 | Emma | 2021-08-01 | 6 |
| 2 | Emma | 2021-08-02 | 17 |
| 3 | Jack | 2021-08-02 | 14 |
| 4 | Emma | 2021-08-04 | 20 |
| 5 | Jack | 2021-08-05 | 5 |
| 6 | Emma | 2021-08-07 | 1 |
+------+----------+------------+ ----------+
+------+----------+-------------+ ----------+
| id| empleado | recent_date | ventas |
+------+----------+-------------+ ----------+
|5 | Jack| 2021-08-05 |5 |
|6 | Emma| 2021-08-07 |1 |
+------+----------+-------------+ ----------+
Explicación
La clave de este problema es dividirlo en dos partes. El primer
objetivo es identificar la fecha de venta más reciente de cada
empleado. Este es el aspecto de la salida de la subconsulta r:
+----------+ --------------+
| empleado | recent_date |
+----------+ --------------+
| Emma | 2021-08-07 |
| Jack, 2021-08-05.
+----------+ --------------+
El segundo objetivo es recuperar las columnas id y sales en la
salida final, lo que se hace utilizando el JOIN en la segunda mitad
de la consulta .
Posibles ampliaciones
Una alternativa a la solución GROUP BY es utilizar una función de
ventana (OVER ... PARTITION BY ...) con una función
FIRST_VALUE- tion, que devolvería los mismos resultados.
Encontrará más detalles en la sección "Funciones de ventana" en
la página 250 del capítulo 8.
+-----------+
| Nombre_id |
+-----------+
| 1_Botas |
| 2_Pumpkin |
| 3_Tiger |
+-----------+
Posibles ampliaciones
El capítulo 7, Operadores y funciones, cubre otras formas de
trabajar con valores de cadena además de CONCAT, incluyendo:
+------+ ---------------+
| nombre | calories_list |
+------+ ---------------+
| ally | 80,75,90 |
| jess | 100,92 |
+------+ ---------------+
Este código funciona en MySQL y SQLite. Sustituya GROUP_CON
CAT(calories) por lo siguiente en otros RDBMS:
Oracle
LISTAGG(calorías, ',')
PostgreSQL
ARRAY_AGG(calorías)
Servidor SQL
STRING_AGG(calorías, ',')
Solución
En la mayoría de los SGBDR, existe una tabla especial que
contiene todos los nombres de tablas y columnas. La Tabla 10-1
muestra cómo consultar esa tabla en cada RDBMS.
La última línea de cada bloque de código es opcional. Puede
incluirla si desea limitar los resultados a una base de datos o un
usuario concretos. Si se excluye, se devolverán todas las tablas.
Tabla 10-1. Buscar todas las tablas que contienen un nombre de columna
específico
RDBMS Código
MySQL SELECT nombre_tabla,
nombre_columna FROM
esquema_informacion.columnas
WHERE nombre_columna LIKE
'%ciudad%'
AND esquema_tabla = 'mi_nombre_db';
NOTA
SQLite no tiene una tabla que contenga todos los
n o m b r e s d e las columnas. En su lugar, puede
mostrar manualmente todas las tablas y luego ver los
nombres de las columnas dentro de cada tabla:
.tablas
pragma información_tabla(mi_tabla);
Posibles ampliaciones
El capítulo 5, Creación, actualización y eliminación, cubre más
formas de interactuar con bases de datos y tablas, incluyendo:
+------+ --------------------+
| Nombre |
+------+ --------------------+
| 101 Macarrones con queso
| 102 | Teclado MIDI |
| 103 | Tarjeta del día de la madre |
+------+ --------------------+
+------+ --------------+
| Nombre |
+------+ --------------+
| 102 | Regalo técnico| --> Teclado MIDI
| 103 | Tarjeta de vacaciones | --> Tarjeta del día de
la madre
+------+ --------------+
Solución
Utilice una sentencia UPDATE para modificar los valores de una tabla
utilizando la función
ACTUALIZAR .SET.....sintaxis. La Tabla 10-2 muestra cómo hacerlo en
cada RDBMS.
Tabla 10-2. Actualizar una tabla cuyo ID coincide con el de otra tabla
RDBMS Código
MySQL UPDATE ofertas
d,
productos
p
+------+ -------------------+
| Nombre |
+------+ -------------------+
| 102 | Teclado MIDI |
| 103 | Tarjeta del día de la madre |
+------+ -------------------+
ADVERTENCIA
Una vez ejecutada la sentencia UPDATE, los resultados
no pueden deshacerse . La excepción es si se inicia una
transacción antes de ejecutar la sentencia UPDATE.
Palabras finales
Este libro cubre los conceptos y palabras clave más populares de
SQL, pero sólo hemos arañado la superficie. SQL se puede
utilizar para realizar muchas tareas, utilizando una variedad de
enfoques diferentes. Te animo a seguir aprendiendo y
explorando.
Te habrás dado cuenta de que la sintaxis SQL varía mucho
según RDBMS. Escribir código SQL requiere mucha práctica,
paciencia y buscar la sintaxis. Espero que esta guía de bolsillo de
te haya resultado útil para ello.
317
318 | Índice
>= (mayor o igual que), 183 al renombrar c o l u m n a s ,
\ (barra invertida) escapar 44
expresiones regulares en utilizar con alias de tabla, 61
MySQL, 211 palabra clave ASCENDING
\d (dígitos) en expresiones (ASC), 86
regulares, 211, 216 Codificación ASCII frente a
_ (guión bajo), uso con LIKE, Unicode, 159
188 operadores de asignación, 191
operador || (concatenación), 203, atomicidad, 138
309 atributos, 11
~ (tilde) soporte limitado de AUTOINCREMENTO, 110
expresiones regulares en Función AVG, 191
PostgreSQL, 215 cláusula ROWS
BETWEEN,
A utilización con, 259
valor absoluto, 194
funciones de agregación, 191- B
193 agregar filas en una sola ENTRE operador, 179, 184
valor o lista, 245, 311 tipos de datos binarios, 175
CONTAR, 80 valores binarios, 174
múltiple, en GROUP BY, 244 almacenar archivos externos
frente a funciones de como, 174 bits, 154
ventana, 250 operadores bitwise, 191
alias, 44 tipo de datos BLOB, 176
columnas de aliasing, 57 tipos de datos booleanos,
aliasing subqueries, 70 173
columna frente a tabla, tipo de datos bytea (PostgreSQL),
60 176 bytes, 154
Palabra clave ALL, 63
Privilegios ALTER, 115 C
sentencias ALTER TABLE, 115, Palabra clave CASCADE, 128
118 precaución con,
nombre de columna ambiguo 129 insensibilidad a
(error), 60 las mayúsculas
Operador AND, 75, 179, 180, 181 palabras clave en SQL, 42
Normas ANSI, 39-41 decidir si patrones LIKE en
se utilizan en MySQL,
escribir código SQL, 40 SQL Server y SQLite, 188
decidir qué utilizar en SQL expresiones regulares en
código, 41 MySQL, 211
Función ARRAY_AGG, 191, 242, en SQL, 7
310 mayúsculas y minúsculas
Palabra clave AS alias entre comillas dobles, 59
alias de columna, 58, 60 patrones LIKE en Oracle y
PostgreSQL, 188
319
320 | Índice
cláusulas principales, 54
expresiones regulares en
nube, bases de datos alojadas
Post- greSQL, 215
en, 22 soluciones de
sentencias CASE, 237, 238-242
almacenamiento basadas en la
alternativa a la opera-
nube
PIVOT
tión, 264
utilizando en lugar de la
función DECODE de
Oracle, 40
caso, cambiando por una
cadena, 200 función CAST
conversión de cadena a tipo
de datos datetime, 230
conversión a un tipo de dato
numérico, 198-199
conversión a un tipo de
datos de cadena, 217
que hace referencia a un
valor de fecha, 161 que hace
referencia a un valor de
fecha-hora,
164
referenciar valor de
tiempo, 163 tipo de datos
CHAR, 157 tipos de datos de
caracteres, 156
c o d i f i c a c i ó n ASCII
frente a Unicode, 159
codificaciones Unicode, 159
VARCHAR, CHAR y
TEXTO, 157
caracteres, recorte de alrededor
de cadenas, 201-203
Función CHARINDEX, 204
CHECK, 103 DROP CHECK y
DROP
RESTRICCIÓN, 123
cláusulas, 7, 45, 51, 53
operadores y funciones en,
179
orden de las cláusulas en la
sentencia SELECT, 8
orden de ejecución en la
sentencia SELECT, 9
ejemplo de consulta con seis
Índice 319
múltiples, recuento de
requerir consultas SQL en, xi
combinaciones únicas, 65
función COALESCE, 86, 235,
múltiple, en GROUP BY,
297
244 calificar nombres de
ejemplos de código de este
columna, 59 renombrar, 116
libro, xv alias de columna, 68,
renombrar con alias, 44
271
actualizar datos en, 124
con distinción entre
símbolo del sistema, 15
mayúsculas y
para MySQL, 17
minúsculas y
para Oracle, 18
puntuación, 59
para PostgreSQL,
creación, 57
18 para SQL
frente a alias de tabla,
Server, 19 para
60 uso con
SQLite, 16
subconsultas en la
comentarios, 48
cláusula SELECT, 62
comando COMMIT, 138
nombres de columnas, búsqueda
confirmar cambios con, 140
de, 311 columnas, 11
no ROLLBACK después de,
añadir a una tabla, 117
141
eliminar de una tabla, 118
expresiones comunes de tabla
mostrar nombres de
(CTE), 291-301
columnas en
no recursivo, 291-295
salida SQLite, 16
recursivo, 295-301
visualización para una
frente a subconsultas, 293-
tabla, 117 filtrado por
295 ventajas de las CTE,
columna en
294
cláusula WHERE, 74
320 | Índice
tabla, 120 clave ajena,
operadores de comparación, 182-
borrado de tabla
189
con, 128
ENTRE, 184
modificar en una tabla, 122
EXISTE, 185
IN, 186
IS NULL, 187
palabras clave, 183
LIKE, 187
símbolos, 183
índices compuestos, 131
llave compuesta, 105
Función CONCAT, 309
concatenar cadenas
Función CONCAT, 203
texto de varios campos en un
solo campo, 308-311
concatenar texto de
campos en varias
filas, 310-311
concatenar texto de
campos en una sola
fila, 309
operador ||
(concatenación), 203
enunciados condicionales, 47, 75,
183
(véase también predicados)
conexiones (base de datos)
conectar la herramienta de
base de datos a la base de
datos, 23
configuración para Python,
26-29 configuración para R,
31-34
constantes, 144
(véase también literales)
palabra clave CONSTRAINT,
102
restricciones, 101, 106, 120-124
añadir a una tabla, 122
suprimir antes de suprimir
una col-
umn, 118
borrado de una tabla, 123
visualización para una
Índice 321
DISTINCT, 64, 304
no permitir valores
contando a partir de 1 en SQL, 205
NULL en una
sentencias CREATE
columna, 102
para bases de datos, 96
requerir valores únicos en
para índices, 131
columna, 104
privilegios de ejecución, 95, 100,
restringir valores en
132, 135
columna, 103
para mesas, 98, 100
configuración de valores
para vistas, 134
por defecto en col-
Crear, Leer, Actualizar y Borrar
m i n a c i ó n , 103
(ver operaciones CRUD)
especificar clave ajena,
UNIÓN CRUZADA, 271, 272, 275, 281
106 especificar clave
sintaxis, 273
primaria, 105
Operaciones CRUD, 6, 91-142
Función CONVERT, 231
para bases de datos, 91-97
subconsultas correlacionadas,
para índices, 129-132
62 problemas de
para mesas, 97-129
rendimiento con, 62
con la gestión de
Función COUNT, 80, 191
transacciones, 138-142
Cláusula HAVING
para las vistas, 133-137
referida a,
Archivos CSV, inserción de datos
84
en una tabla, 112-115
HAVING COUNT en
CTEs (ver e x p r e s i o n e s
consulta, 306
comunes de la tabla)
utilizando con
322 | Índice
159 controladores de bases de
Palabra clave CUBE, 249
datos, 20
fecha u hora actual, obtener,
instalación del controlador
218-220
para Python, 25
Función CURRENT_DATE, 47,
instalar controlador para R, 31
218
archivos de base de datos, 22
Función CURRENT_TIME, 218
CURRENT_TIMESTAMP func-
tión, 218
D
flujo de trabajo del análisis de
datos, 24
Lenguaje de control de datos
(DCL), 51 Lenguaje de definición
de datos (DDL),
50
Lenguaje de manipulación
de datos (DML), 50
modelos de datos, 10-12, 91
frente a esquemas, 93
Lenguaje de consulta de datos
(DQL), 50 tipos de datos, 143-178
elegir para una columna,
145 de columnas, 97
datos datetime, 161-
172 tipos de datos
datetime,
165-172
datos numéricos, 147-154
tipos de datos decimales,
150 tipos de datos de
coma flotante,
151
tipos de datos
enteros, 148-
150
otros datos, 172-178 Tipos
de datos booleanos,
173 archivos externos,
173-178
datos de cadenas, 154-
161 tipos de datos de
caracteres,
156-159
tipos de datos Unicode,
Índice 323
esquemas, 92
Sistemas de gestión de bases
mostrando en MySQL, 17
de datos ( SGBD), 3
m o s t r a n d o en
objetos de base de datos, 91
Oracle, 18 mostrando en
herramientas de bases de datos, 13, 20-
PostgreSQL, 19 mostrando
24
en SQL Server, 20
comparaciones de, 21
mostrando en SQLite, 16
conexión a una base de
SQL, 1
datos, 22
cambiar a otro, 95 DATE
bases de datos, 10, 91-97
tipo de datos, 143
aproximadamente, 1
Palabra clave DATE, 161
crear, 22, 95
Función DATEDiFF, 222
modelo de datos, 10
fechas, 161
modelo de datos frente a esquema,
conversión de cadena a tipo de
93 supresión, 96
datos de fecha, 232
visualización del nombre
tipos de datos (véase tipos de
de la corriente, 94
datos datetime)
visualización de los
formatos de fecha,
nombres de los
232 unidades de
existentes, 93
fecha en diferentes
NoSQL, 2
SGBDR, 226
calificar tablas con
valores de fecha, 161
nombre de base de
especificadores de
datos, 60
formato datetime, 233
consulta, 54
324 | Índice
definición de datos),
rellenar las fechas que faltan
50
con CTE recursivo, 295-
Tipo de datos DECIMAL, 153
298
datos datetime, 161-172 tipo de
datos DATETIME, 166 funciones
datetime, 43, 161,
218-234
convertir cadena a tipo de
datos datetime, 230-234
aplicar función date a
columna de cadena,
233 utilizando la función
CAST, 230 utilizando
CADENA_A_FECHA,
TO_DATE, y CON-
VERT, 231
determinar el día de la
semana para una fecha,
228
extraer parte de la fecha o la
hora, 226-228
encontrar la diferencia entre
dos fechas, 221
encontrar la diferencia entre
dos fechas, 224
encontrar la diferencia entre
dos tiempos, 222
devolver la fecha o la hora
actual, 218-220
redondear la fecha a la unidad
de tiempo más próxima,
229
en SQLite, 171
restar fecha u hora inter- val,
220
Palabra clave DATETIME, 164
valores fecha-hora, 161-165
valores fecha y hora, 164
valores fecha, 161
tipos de datos datetime, 165-
172 valores de tiempo, 162
Archivos DB (ver archivos de base
de datos)
DCL (Lenguaje de control de
datos), 51 DDL (Lenguaje de
Índice 325
tratamiento distribuido de datos
decimales
marcos, inter- faces tipo
tipos de datos decimales,
SQL, xi
150 valores decimales, 147
DML (l e n g u a j e de
programación declarativa, 38
manipulación de datos), 50
Restricción DEFAULT, 103
documentos, almacenamiento
Sentencias DELETE, 101, 120,
para uso en SQL, 173
140, 142
Tipo de datos DOUBLE, 152
operadores y funciones en,
doble precisión (tipos de datos
180
de coma flotante), 152
Función DENSE_RANK, 252
DQL (Lenguaje de consulta de
frente a ROW_NUMBER
datos), 50 Sentencias DROP
y
DROP CHECK y DROP
RANK, 254
CONSTRAINT, 123
tablas derivadas, 69
para bases de datos, 96
Palabra clave DESCENDING
para índices, 132
(DESC), 86
para mesas, 101, 128
dígitos, 154
para vistas, 137
palabra clave DISTINCT, 63,
duplicados
304 utilización con
excluir filas duplicadas con UNION,
COUNT, 80 utilización
287
con COUNT en
búsqueda de filas con valores
cláusula SELECT, 64, 304
duplicados, 303-306
326 | Índice
preservar las filas valores en coma flotante,
duplicadas con 147 claves externas, 11
UNION ALL, 287 borrar tabla con referencia a clave
eliminación de filas externa, 128
duplicadas del especificación, 106
resultado con DIS- preguntas frecuentes
TINCT, 64, 304 (Preguntas frecuentes), 303-315
E
Palabra clave números de coma fija, 150 tipo
ESCAPE, 189 de datos FLOAT, 152 tipos de
secuencias de escape datos de coma flotante, 151
sólo para cadenas entre
comillas simples, no
signos de dólar ($$),
156
secuencias de escape en una
cadena, 155 operador EXCEPT,
289
orden de ejecución, 291
operador EXISTS, 185
JOIN contra, 185
NO EXISTE, 186, 186
expresiones, 47
(véase también expresiones
comunes de la tabla)
extensiones para SQL, 38
archivos externos (imágenes,
documentos, etc.), 173
Función EXTRACT, 233
F
Valores FALSE y TRUE, 172
rutas de archivos al escritorio
(ejemplo), 114
filtrado de datos
alternativas a la cláusula
WHERE, 78
utilizando la cláusula
HAVING, 83 utilizando la
cláusula WHERE, 73-77
filtrado de columnas, 74
filtrado de subconsultas,
75-77
función FIRST_VALUE, 255
Índice 327
concatenar texto de varios duplicados, 305-
campos en un solo 306
campo, 308 seleccionar filas con valor
de campos en una sola máximo para otra columna,
fila, 308 306-308
de campos en varias cláusula FROM, 8, 46, 66-73, 78
filas, 310 datos de varias tablas,
búsqueda de todas las mediante JOIN, 66
tablas que contienen alias de tabla, 67
un nombre de orden de ejecución en la sentencia
columna específico, SELECT, 9
311-313 subconsultas, 69-73
encontrar filas que beneficios de, 72-73
contienen valores alias de tabla definidos en,
duplicados, 303-306 61
devolver todos los com- UNIÓN EXTERNA COMPLETA, 272,
únicos 278
binaciones, 304 funciones, 42, 179, 191-235
devolviendo sólo las agregado, 191, 193
filas con datetime, 218-234
valores más común, 180
null, 234
328 | Índice
numérico, 193-199 H
operadores frente a, cláusula HAVING, 8, 83-85
179 filtrado de resultados de
cuerda, 199-218 GROUP BY, 83
HAVING COUNT en la consulta,
G
comando go (SQL Server), 20 191, 245, 310
función GREATEST, 193 GUI (interfaces gráficas de
Cláusula GROUP BY, 8, 46, 78- usuario) en herramientas de
82, bases de datos, 13
242-247 uso de la herramienta de base
agregar filas en un único de datos GUI para
valor o lista, 245 modificar la tabla, 119
recogida de filas, 79
agrupación por múltiples
col-
umnas, 243
cláusula HAVING siguiente,
83 columnas no agregadas en,
192 orden de ejecución en
SELECT
declaración, 9
en consulta seleccionando
filas con valor máximo,
308
pasos a seguir al utilizar, 82
resumen de filas en
grupos, 80
utilizar para crear tabla
resumen, 243
agrupación y resumen, 237, 242-
250
cláusula GROUP BY, 242
utilizando ROLLUP, CUBE
y
AGRUPACIÓN DE
CONJUNTOS, 247
palabra clave CUBE, 249
palabra clave
GROUPING SETS-
palabras, 249
Palabra clave ROLLUP,
248 Palabras clave GROUPING
SETS, 249 Función
GROUP_CONCAT,
Índice 329
306 I
operadores y funciones en, identificadores, 43
179 comillas dobles ("") entre
orden de ejecución en la sentencia comillas, 49
SELECT, 9 denominación, 43
en la búsqueda de valores IF EXISTS palabras clave, 128
duplicados, 305 IF NOT EXISTS palabras clave,
requisito de seguir 100 imágenes, 144
GROUP BY, 83 en ficheros externos, 173
utilizado con SELECT, orden de inmutabilidad, claves primarias,
ejecución, 84 106 programación imperativa,
utilizar para filtrar datos, 37
78 WHERE frente a, 84 Operador IN, 186
valores hexadecimales, 174 NO EN, 181, 186
Gestor de paquetes índices, 129-132
Homebrew índice de libros frente a índice
(Linux y macOS), 15 SQL, 129
Cómo puedo... (ver preguntas crear para acelerar las
frecuentes) consultas, 131
supresión, 132
330 | Índice
número límite de, 131 sintaxis JOIN versus UNION,
INNER JOIN, 69, 271, 272, 284 sintaxis JOIN ... ON ..., 67,
276-277 276
en la búsqueda de valores LEFT JOIN, 277
duplicados, 306 en consulta seleccionando
en consulta seleccionando filas con valor máximo,
filas con valor máximo, 307
308 reescritura de subconsultas
sentencias INSERT, 98, 110, 120 con, 63, 72
operadores y funciones en, UNIÓN DERECHA, 278
180 autounión, 282-284
instalación, RDBMS, 15 sintaxis para unir tablas, 272
Función INSTR, 204 USAR y UNIR NATURAL
Tipo de datos INTEGER, 98, 143, atajos, 279-281 usar en
146, lugar de correlacionado
171 subconsulta, 62
números enteros utilización de la cláusula JOIN
dividir por un entero, 190 en la cláusula FROM, 66
tipos de datos enteros, 148
valores enteros, 147 K
muestra de tipos de datos
enteros, 145
operador INTERSECT, JOIN por defecto a INNER
290 orden de JOIN, 69, 271
ejecución, 291 tipos de unión, 271
intervalos
tipo de datos INTERVALO,
172 restando la fecha o la
hora inter-
val, 220
Operador IS NOT NULL, 187
Operador IS NULL, 48, 187
J
se une, 270-274
fundamentos de, 274
UNIÓN CRUZADA, 281
en consulta de filas
duplicadas, 305 EXISTS
frente a JOIN, 185 FULL
OUTER JOIN, 278 INNER
JOIN, 274, 276-277
cláusula JOIN, 270
desglose de, 271
condición de unión, 271
Índice 331
palabras clave, 7, 42, 51 Función LENGTH, 199, 217
insensible a mayúsculas y Función LEN en SQL
minúsculas en SQL, 42 Server,
operadores como, 180 217
operador LIKE, 184, 187
expresiones regulares
L limitadas
Función LAG, 258, 297 en SQL Server, 216
Función LAST_VALUE, 255
NO ME GUSTA, 188
Función LEAD, 259
búsqueda de texto en
Función LEAST, 193
cadenas, 204
LEFT JOIN, 272, 277, 296
cláusula LIMIT, 78, 88
LEFT OUTER JOIN, 278
332 | Índice
102
Función LISTAGG, 191, 242, 310
literales, 144
localhost, 28, 33
operadores lógicos, 181
Función LOWER, 200
Funciones LTRIM y RTRIM,
202
M
funciones matemáticas, 194
operadores matemáticos, 189
Función MAX, 191, 193, 245
Microsoft SQL Server (véase SQL
Servidor)
función MIN, 191, 193 datos
omitidos
desde archivo CSV,
interpretaciones por
RDBMS, 114
sustitución de los valores que
faltan por otro valor, 103
MongoDB, 3
MySQL
MySQL Workbench, 21
esquemas y bases de datos, 93
escribir código SQL con, 17
N
convenciones de denominación
alias de columna, 59
identificadores, 43
UNIÓN NATURAL, 273
precaución con, 281
utilizando para
reemplazar INNER
JOIN, 280
subconsultas no correlacionadas,
62
CTEs no recursivos, 291
NoSQL, 2
restricción NOT NULL, 102, 106
operador NOT, 181
Función NTH_VALUE, 256
Valores nulos, 48
permitiendo en una columna,
Índice 333
CAST, conversión a
desde archivo CSV,
un tipo de dato
interpretaciones por
numérico, 198-
RDBMS, 114
199
IS NULL y IS NOT NULL
generación de números
operadores, 187
aleatorios, 196
operador NOT IN frente a
matemáticas, 194
NOT EXISTS, 186
redondeo y
Restricciones de
truncamiento de
c o l u m n a NULL y
números, 197
NOT NULL, 102
Tipo de datos NVARCHAR, 160
funciones nulas, 234
VARCHAR frente a, 160
NULL literal, 145
sustituida por la f u n c i ó n
COALESCE, 86 O
datos numéricos, 147-154 mapeadores relacionales de objetos
comparar columna (ORM), 30
numérica cláusula ON, 67
a columna de cadena, JOIN ... ON ... sintaxis,
198 tipos de datos condiciones m u l t i p l e s
decimales, 150 tipos de en, 277
datos de coma flotante, 151 en, 179 sustituir por
tipos de datos enteros, 148 USING en
valores numéricos, 147 se une, 279
funciones numéricas, 43, 147, operadores, 179-191
193-199 comparación, 182-189
334 | Índice
frente a funciones, 179 P
en condiciones join, marcos de datos pandas, 29
271 lógicas, 181
matemáticas, 189
más común, 180
frente a predicados, 182
unión, 285-291
utilizar para combinar
predicados, 75
Operador OR, 75, 179, 181, 182
Oracle
en comparación con otros
RDBMS, 4
Oracle SQL Developer, 21
lenguajes de procedimiento
SQL
(PL/SQL), 38
esquemas y usuarios, 93
escribir código SQL con,
17
Base de datos Oracle (véase
Oracle)
cláusula ORDER BY, 8, 85-88,
252
ordenación alfabética
a s c e n d e n t e , 86
imposibilidad de utilizar en
subconsultas, 88
orden de ejecución en la
sentencia SELECT, 9
ordenar por columnas y
expresiones no en
SELECT, 87
clasificación por orden
descendente, 87
en las consultas UNION,
288 orden de ejecución
C l á u s u l a s SELECT y
HAVING, 84
Declaración SELECT, 9
operadores sindicales, 291
Palabra clave OVER, 252
SOBRE ... PARTICIÓN POR ...
sintaxis, 252, 308
Índice 335
sentencia CASE como
PARTICIÓN POR palabras
alternativa a, 264
clave, 252, 262
pivotar y despivotar, 237,
contraseñas
263-267
para conectarse a la
descomposición de los
herramienta de base de
valores de una columna
datos, 23 para la conexión
en varias columnas, 263-
Python a
265
base de datos, 28
lista de valores de varias
para conexión R a base de
c o l u m n a s en una
datos, 33
sola columna, 265-267
coincidencia de
PL/SQL (lenguaje
patrones
procedimental SQL), 38
operador LIKE,
función POSITION, 204
187
sintaxis POSIX, expres-
(véase también
regulares
expresiones
siones, 213, 215
regulares)
PostgreSQL
rendimiento
en comparación con otros
subconsultas
RDBMS, 4
correlacionadas,
base de datos por defecto, postgres,
problemas con, 62
97 pgAdmin, 21
optimizar el código, 77
escribir código SQL con, 18
acelerar las consultas
precisión, 151
con
tipos de datos de coma
índices, 131
flotante de doble
Operación PIVOT, 263-265
precisión, 152
336 | Índice
131
tipos de datos de coma
actualización de filas con
flotante de precisión
resultados de, 126
única, 152
predicados, 47, 75
combinación múltiple,
mediante operadores, 75
operadores frente a, 182
claves primarias, 11, 105-106
buenas prácticas, 106
claves externas que hacen
referencia a, 106 lenguajes de
programación
comparación de SQL con
otros, 37
escritura de código SQL en,
13, 24-35
Pitón, 25-31
R, 31-35
puntuación en alias de columna,
59 Python, 37
conexión a una base de
datos, 25-29
conexión a RDBMS y
escritura de código SQL,
14
Paquete SQLAlchemy, 30
uso de SQL con, xiii
escritura de código SQL
dentro de,
29-31
Q
calificar nombres de columnas,
59, 68
calificar nombres de tablas, 60
consultas, 6-10, 53-89
fundamentos, 53
combinar con UNION, 287
crear vista para guardar
resultados
de, 135
inserción de resultados en
una tabla, 110
aceleración mediante la
creación de un índice,
Índice 337
RANGO ENTRE versus
conceptos de consulta,
FILAS ENTRE, 262
avanzados, 237-267
comprobar si el valor está
sentencias CASE, 238-242
entre, 184
agrupar y resumir,
Función RANK, 252
242-250
frente a ROW_NUMBER y
pivotar y despivotar,
DENSE_RANK, 254
263-267
Software RDBMS, 13
funciones de ventana, 250-
RDBMSs
262 comillas en SQL, 48
SQL ANSI frente a SQL
específico de RDBMS, 39
R comparaciones de, 4
Idioma decidir qué RDBMS
conexión a una base utilizar
de datos, 31-34 uso, 14
conexión a RDBMS y MySQL, 17
escritura de código Oracle, 17
SQL, 14 PostgreSQL, 18
uso de SQL con, xiii SQL Server, 19
escribir código SQL SQLite, 15
dentro de, 34 generador de definido, 3
números aleatorios, 196 uso de SQLAlchemy con, 30
rangos
338 | Índice
filas
variaciones en la sintaxis
SQL, 3, 315
escribir código SQL con,
14 tipo de datos REAL, 171
CTEs recursivas, 291, 295-
301
rellenar las filas que faltan en
la secuencia de datos,
295-298
devolver a todos los padres
de filas de niños, 298-301
Palabra clave RECURSIVE, 292
Función REGEXP (MySQL), 210
Función REGEXP_REPLACE,
208
en Oracle, 212
en PostgreSQL, 216
expresiones regulares, 184, 209-
217 notas importantes sobre,
210 en MySQL, 210
en Oracle, 211
en PostgreSQL,
214 en SQL Server,
216
utilizar en Oracle para extraer
subcadenas, 207
utilizar en Oracle para buscar
subcadenas, 206
Sistemas de gestión de bases de
datos relacionales (véase
SGBDR)
bases de datos relacionales, 1
relación, definida, 11
servidores remotos, bases de
datos en, 22 renombrar
de columnas, 116
de las mesas, 116
Función REPLACE, 207
conjuntos de resultados, 54
RIGHT JOIN, 272, 278
RIGHT OUTER JOIN, 278
comando ROLLBACK, 138
deshacer cambios con, 141
Palabra clave ROLLUP, 248
redondeo de números, 197
Índice 339
rangos en cada grupo,
agregación en un único
257
valor o lista, 245
dentro de una función
recoger en GROUP BY, 79
ventana, 251
suprimir de una tabla, 120
Funciones RTRIM y LTRIM,
visualizar para una tabla,
202
119 insertar en una tabla,
120 clasificar en una tabla,
252 FILAS ENTRE versus S
INTERVALO ENTRE, 262 escala, 151
actualizar valores en, 125 esquemas, 91
actualizar con resultados modelos de datos frente a, 93
de consulta, calificar tablas con esquema
126 nombre, 60
FILAS ENTRE cláusula, 259 en bases de datos SQL, 2
FILAS ENTRE UNBOUN- definiciones variables
Cláusula DED, 261 en
Función ROW_NUMBER, 252, SGBDR, 93
252 cláusula SELECT, 8, 46, 55-66
frente a RANK y columnas de aliasing, 57
DENSE_RANK, alias con distinción entre
254 mayúsculas y
utilizando en subconsulta minúsculas y
para devolver varios puntuación, 59
COUNT y DISTINCT en, 64
340 | Índice
Management Stu-
DISTINTO en, 63
dio, 22
operadores y funciones en,
179
orden de ejecución en la
sentencia SELECT, 9
columnas de calificación, 59
tablas de clasificación, 60
selección de subconsultas, 61-
63
sentencias SELECT, 7, 45, 140
cláusulas en, 7, 45
combinar resultados de dos o
más con UNION, 285
operadores y funciones en,
180
autounión, 274, 282-284
semi-unión, 185
separadores, 246, 311
SIMILAR A, limitado regular
soporte de expresiones en
Post- greSQL, 215
precisión simple (tipos de datos
de coma flotante), 152
Tipo de datos SMALLINT, 146
ordenación
orden ascendente y
descendente, 86
por columnas y expresiones
no incluidas en la lista
SELECT, 87
SQL
aproximadamente, 1
comparación con otros
lenguajes de
programación, 37
papel integral en el paisaje
de datos, xi
resumen del lenguaje, 51
búsqueda de sintaxis en línea,
4 sublenguajes, 50
SQL Server, 5
en comparación con otros
RDBMS, 4
base de datos por defecto,
master, 97 SQL Server
Índice 341
concatenar cadenas, 203
escribir código SQL con,
convertir a cadena de datos
19 sentencias SQL, 6
tipo, 217
Paquete SQLAlchemy
borrar texto de una cadena,
(Python), 30
208
SQLite
extraer parte de una cadena,
en comparación con otros
206
RDBMS, 4
encontrar la longitud de una
base de datos almacenada
cadena, 199 reemplazar texto
en archivos externos,
en una cadena, 207 buscar
94
texto en cadenas,
DB Browser para SQLite,
203
21 RDBMS más rápido
recorte de c a r a c t e r e s
de configurar, 14
no deseados alrededor
esquema en estrella, 92
de las cadenas,
Empezar los viernes con la
201-203
avena casera de la
uso de expresiones
abuela (mnemotecnia
regulares, 209-217
para las cláusulas), 8
cuerdas, 154-161
INICIAR TRANSACCIÓN, 138
conversión a decimal para
declaraciones, 6,
comparar con un número,
45
199
cláusulas en,
tipos de datos de caracteres, 156
45
comparar columna de cadena
funciones de cadena, 43, 154, 199-
con
218 cambiar mayúsculas y
columna numérica, 198
minúsculas de una cadena, 200
342 | Índice
frente a la cláusula WITH, 71
conversión a tipo de datos
envolver DISTINCT en y
datetime, 230-234
utilizando COUNT en, 65
comillas simples ('') que
SUBSTR o SUBSTRING func-
encierran, 49 f u n c i o n e s
tión, 206
d e c a d e n a a fecha, 162
subcadenas, búsqueda en cadenas,
funciones de cadena a fecha-
205 función SUMA, 191, 251
hora,
164
funciones de cadena a
tiempo, 162 valores de
cadena, 154, 156
alternativa al uso de
comillas simples, 155
secuencias de escape
para, 155 tipos de datos
Unicode, 159
Función STRING_AGG, 191,
242, 310
Función STR_TO_DATE, 231
sublenguajes (SQL), 50
subconsultas
expresiones comunes de la
tabla frente a, 293-295
correlacionadas frente a no
correlacionadas, 62
correlacionado, problemas
de rendimiento con, 62
filtrado de datos en, 255, 256
dentro de la cláusula FROM,
69-73
ventajas de la utilización,
72-73 orden de ejecución
para
ejemplo de consulta,
69-71 nombrar
temporalmente con
alias, 44
sin cláusulas ORDER BY en,
88 dentro de la cláusula
SELECT, 61 utilizando en
lugar de una vista, 134 frente
a vistas, 135
dentro de la cláusula
WHERE, 75 ventajas de,
76
Índice 343
creación de una tabla con
con la cláusula ROWS
con- ceptos, 101-105
BETWEEN
no permitir valores NULL
UNBOUNDED, 261
en columna, 102
Los pies sudorosos darán
requerir valores únicos en
olores horribles
columna, 104
(mnemotecnia para clau-
restringir valores en
ses), 8
c o l u m n a con
CHECK, 103
T establecer valores por
alias de tabla, 60 defecto en la
alias de columna columna, 103
frente a, 60 uso en crear tabla con claves
cláusula FROM, 67 primarias y foráneas,
nombres de tablas, 105-108 especificar clave
visualización, 311 tablas, 1, 10 foránea,
combinar con UNION y 106
eliminar filas especificar clave
duplicadas, 286 primaria, 105
crear tabla simple, 98 creación de una nueva base de
crear tabla no datos, 22
existente, 100 tablas derivadas, 69
crear tabla con campo visualización de los nombres
generado de las tablas existentes,
automáticamente, 108 100
344 | Índice
múltiples,
insertar resultados de
269-301
consulta en, 110-112
TCL (l e n g u a j e de control de
insertar datos de archivos
transacciones), 51
de texto en, 112-115
modificar, 115-129 añadir
una columna, 117
añadir una restricción,
122 añadir filas, 120
cambiar el tipo de datos
de una
columna, 146
b o r r a r u n a tabla,
128 borrar columna de
una
mesa, 118
eliminar restricciones, 123
borrar filas, 120 borrar
tabla con foreign
referencia clave, 128
visualización de
columnas, 117
visualización de
restricciones,
120
visualizar filas, 119
modificar una restricción,
122
renombrar una columna o
tabla, 115-117
actualizar columna de
datos, 124
actualización de filas de
datos, 125 actualización
de filas con consulta
resultados, 126
calificar nombres de
tablas, 60 renombrar con
alias, 44 mostrar en
MySQL, 17 mostrar en
Oracle, 18 mostrar en
PostgreSQL, 19 mostrar
en SQL Server, 20 mostrar
en SQLite, 16 requisitos
SQL para, 97 vistas frente
a, 54, 133 trabajar con
Índice 345
de datos datetime)
ventana de terminal, escribir
formatos de tiempo,
código SQL en, 13, 15
232 unidades de
(véase también símbolo del
tiempo en diferentes
sistema)
SGBDR, 227
texto
valores temporales, 162
concatenación de varios
palabra clave TIME, 163
campos en un solo
tipo de datos TIMESTAMP,
campo, 308-311
166 palabra clave
búsqueda de todas las
TIMESTAMP, 164 tipo de
tablas que contienen
datos TINYINT, 146
un nombre de
función TO_DATE, 231
columna específico,
espacios finales
311-313
excluyendo en longitud de
insertar datos de un
cadena, 200
archivo de texto en una
eliminación con RTRIM, 202
tabla, 112-115
Lenguaje de control de
reemplazar en una cadena,
transacciones
207 buscar en una cadena,
(TCL), 51
204
gestión de transacciones, 138-142
TEXTO tipo de datos, 157, 171
beneficios de, 138
tiempo, 161
doble comprobación de
(véase también datos datetime)
cambios antes de
convertir cadena en datos de
COMMIT, 139
tiempo
no ROLLBACK después de
tipo, 230
COM- MIT, 141
tipos de datos (véase tipos
346 | Índice
datos, 124
deshacer cambios con ROLL-
actualización de filas de datos,
BACK, 141
125
transacción, definida, 138
Función TRIM, 200, 201 eliminar
la parte inicial o final
caracteres, 202
valores TRUE y FALSE, 172
truncar tabla existente, 101, 120
truncamiento de números,
197 afinidades de tipo
(SQLite), 98
U
Tipos de datos Unicode, 159
c o d i f i c a c i ó n ASCII
frente a Unicode, 159
UNION ALL, alternativa a
UNPIVOT, 266
operadores sindicales, 284-291
EXCEPTO, 289
INTERSECT, 290
JOIN frente a UNION,
284 orden de ejecución,
291 requisito de
coincidencia
tipos de datos, 287
UNIÓN, 285
con más de dos
mesas, 289
con otras cláusulas, 288
UNION ALL, 287, 296
restricción UNIQUE, 104, 106
filas únicas (véase clave
DISTINCT)
palabra)
Operación UNPIVOT, 265-267
UNION ALL como
alternativa a,
266
sentencias UPDATE, 125
imposibilidad de deshacer
resultados, 314 operadores y
funciones en,
180
actualizar una columna de
Índice 347
Tipo de datos VARCHAR, 98, 143, 157
actualización de la tabla
frente a NVARCHAR, 160
cuyo ID coincide con
VARCHAR2 en Oracle, 110
el de otra tabla, 313
editor de texto vi, 19
actualización de valores
vistas, 133-137
basada en una consulta,
crear para restringir el acceso
127
a las tablas, 133
Función UPPER, 179, 200
crear para guardar los
nombres de usuario
resultados de la consulta,
para conectarse a la
135
herramienta de base de
borrar, 137
datos, 23 para la conexión
visualización de vistas
Python a
existentes, 136 consulta, 54
base de datos, 28
subconsultas frente a, 135
para conexión R a base de
actualización, 137
datos, 33
Cláusula USING, sustitución de
ON en las uniones, 273, 279 W
UTF (Formato de página web de este libro, xvi
transformación Unicode), cláusula WHERE, 8, 46, 73-
159 78 en CROSS JOINs, 282
uso de la sentencia DELETE,
140 f i l t r a d o d e
V columnas, 74, 89 filtrado de
Tipo de datos VARBINARY (SQL subconsultas, 75
Servidor), 176
348 | Índice
frente a HAVING, 84 omitir calcular el total actual, 261
en estado DELETE-. clasificar filas en una tabla, 252
ment, 120 devolver los dos primeros
operadores y funciones en, valores en
179 cada grupo, 257
orden de ejecución en devolviendo el primer valor
código SQL, 9 de cada
en self join, 284 grupo, 255
en la sentencia UPDATE, que devuelve el valor de la fila
126 espacios en blanco anterior, 258 que devuelve el
eliminar los espacios segundo valor en
alrededor de una cada grupo, 256
cadena, 201 ventana, definida, 252
espacios en nombres de alias cláusula WITH
de columna, 59 en expresiones comunes de
en SQL, 49, 51 tablas, 291
funciones de ventana, 237, 250- SGBDR compatibles, 71
262 funciones agregadas subconsultas frente a, 71
frente a, código de trabajo, escribir luego
250 opti-
desglose de, 252 cálculo de mización, 77
la media móvil,
259 Y
AÑO función, 179, 227
Índice 349
350 | Índice
Sobre el autor
Alice Zhao es una científica de datos a la que le apasiona
enseñar y hacer que las cosas complejas sean fáciles de entender.
Ha impartido numerosos cursos de SQL, Python y R como
científica de datos sénior en Metis y como cofundadora de Best
Fit Analytics. Sus tutoriales técnicos en YouTube son conocidos
por ser prácticos, entretenidos y visualmente atractivos.
Escribe sobre análisis y cultura pop en su blog, A Dash of Data.
Su trabajo ha aparecido en Huffington Post, Thrill- ist y Working
Mother. Ha sido ponente en diversas conferencias, como Strata
en Nueva York y ODSC en San Francisco, sobre temas que van
desde el procesamiento del lenguaje natural a la visualización de
datos. Tiene un máster en análisis y una licenciatura en
ingeniería eléctrica, ambos por la Northwestern University.
Colofón
El animal que aparece en la portada de la Guía de Bolsillo SQL es
un salamandra alpino (salamandra atra). Habitual de los
barrancos de los Alpes (por encima de los 1.000 m), la
salamandra alpina destaca por su inusual capacidad para
soportar el frío. Estas criaturas negras y brillantes prefieren los
lugares sombríos y húmedos y las grietas y huecos de los muros
de piedra. Se alimenta de gusanos, arañas, caracoles y pequeñas
larvas de insectos.
A diferencia de otras salamandras, la salamandra alpina da a luz
a juveniles completamente formados. La gestación dura dos
años, pero a mayor altitud (1.400-1.700 m) puede durar hasta
tres. En general, la especie está protegida en todos los Alpes, pero
el cambio climático ha afectado más recientemente a su hábitat
preferido de paisajes rocosos y no demasiado secos.
Muchos de los animales de la portada de O'Reilly están en
peligro de extinción; todos ellos son importantes para el mundo.
La ilustración de la portada es obra de Karen Montgomery,
basada en un grabado en blanco y negro de la Royal Natural His-
tory de Lydekker. Los tipos de letra de la portada son Gilroy
Semibold y Guardian Sans. La fuente del texto es Adobe Minion
Pro; la del encabezamiento, Adobe Myriad Condensed; y la del
código, Dalton Maag's Ubuntu Mono.
Hay mucho más de
donde vino esto.
Descubra libros, vídeos, cursos de
formación en línea en directo y mucho
más de O'Reilly y nuestros más de 200
socios, todo en un mismo lugar.