2.5 Cláusulas básicas de SQL

2.5.1 Selección de campos

  • Seleccionar todas las columnas de una tabla:
  SELECT * FROM Track;  
  • Seleccionar columnas específicas:
  SELECT name, composer FROM Track; 
  • Alias de columna y tabla:
  SELECT name AS Canción FROM Track; 

  SELECT T.name FROM Track AS T;
  • Funciones de agregación:
  SELECT COUNT(*), SUM(UnitPrice), MIN(UnitPrice), MAX(UnitPrice) FROM Track; 

  SELECT AVG(milliseconds) AS 'Duración Media' FROM Track; 
  • Formato:
  SELECT CONCAT(FirstName, ' ', LastName) AS Nombre FROM Employee; 

  SELECT (FirstName || ' ' || LastName) AS Nombre FROM Employee; 

  SELECT ROUND(AVG(Total), 2) AS 'Facturacion Media' FROM Invoice; 

2.5.2 Número de filas (paginación)

  • Obtener las N primeras:
  SELECT * FROM Track
  ORDER BY title ASC
  LIMIT 5;
  • Obtener las N filas siguientes:
  SELECT * FROM Track
  ORDER BY title ASC
  OFFSET 5 LIMIT 5;

2.5.3 Filtrado de Resultados

  • Filtrado de duplicados:
  SELECT DISTINCT FirstName FROM Customer; 

  SELECT COUNT(DISTINCT FirstName) FROM Customer; 
  • Seleccionar filas con condiciones:
SELECT name FROM Track
WHERE UnitPrice < 2.0; 
  • Múltiples condiciones:

    • Operadores: ‘AND’, ‘OR’, ‘LIKE’, ‘NOT’, ‘IS NULL’, ‘IS NOT NULL’ ‘BETWEEN x AND y’, ‘IN (lista)’
  SELECT name FROM Track
  WHERE milliseconds > 120000 AND UnitPrice < 2.0; 
  SELECT name FROM Track
  WHERE composer LIKE 'Metallica' OR composer LIKE 'Ulrich'; 
  • Coincidencias parciales:
  SELECT * FROM Track
  WHERE name LIKE '%Love%'; 
  • ‘%’ : Reemplazo por un conjunto de caracteres

  • ’_’ : Reemplazo por un caracter

  • Rangos:

  SELECT * FROM Track
  WHERE UnitPrice BETWEEN 0.5 AND 1.5; 
  • Valores en una lista:
  SELECT * FROM Track
  WHERE composer IN ('Metallica', 'Ulrich'); 

2.5.4 Ordenación de Resultados

  • Ordenar por una columna:
  SELECT * FROM Track
  ORDER BY title ASC; 

  SELECT * FROM Track
  ORDER BY title DESC; 
  • Ordenar por múltiples columnas:
  SELECT * FROM Track
  ORDER BY composer ASC, title DESC; 

2.5.5 Unión de tablas

  • Intersección por clave primaria / clave foránea:

    • Operador A [INNER] JOIN B: interesección de A y B
  SELECT ar.Name AS Artista, a.Title AS Album
  FROM Artist ar JOIN Album a ON ar.ArtistId = a.ArtistId;
  • Operador A LEFT JOIN B: interesección de A y B, y filas de A sin correspondencia en B
  SELECT ar.Name AS Artista, a.Title AS Album
  FROM Artist ar LEFT JOIN Album a ON ar.ArtistId = a.ArtistId;
  • Operador A RIGHT JOIN B: interesección de A y B, y filas de B sin correspondencia en A

  • A ‘FULL [OUTER] JOIN’ B: interesección de A y B, y filas de A y B sin correspondencia

  • sqlite no soporta directamente RIGHT JOIN ni FULL JOIN

  • Producto cartesiano

  SELECT g.Name AS Genero, m.Name AS Formato
  FROM Genre g CROSS JOIN MediaType m

2.5.6 Agrupamiento

  • Funciones de agregación parciales
  SELECT A.Title AS Album, COUNT(*) AS Canciones, SUM(UnitPrice) AS Precio 
  FROM Album A JOIN Track T ON A.AlbumId = T.AlbumId 
  GROUP BY A.Title; 
  • CONSEJO: Es importante agrupar por clave candidata o superclave. La consulta anterior daría resultados incorrectos si existen dos álbumes diferentes con el mismo título. Mejor:
  SELECT A.Title AS Album, COUNT(*) AS Canciones, SUM(UnitPrice) AS Precio 
  FROM Album A JOIN Track T ON A.AlbumId = T.AlbumId 
  GROUP BY A.AlbumId;
  • Además, también es importante que ese campo de agrupación o algo que garantice la identificación unívoca se presente en los resultados. En el ejemplo anterior sí aparecerían los álbumes por separado, pero no sería posible identificar cuál es cuál en los resultados. Mejor:
  SELECT A.AlbumId, A.Title AS Album, COUNT(*) AS Canciones, SUM(UnitPrice) AS Precio 
  FROM Album A JOIN Track T ON A.AlbumId = T.AlbumId 
  GROUP BY A.AlbumId;
  • Incluso mejor, si asumimos que no habrá un artista con dos álbumes con el mismo nombre:
  SELECT AR.Name AS Artista, AS Album, COUNT(*) AS Canciones, SUM(UnitPrice) AS Precio 
  FROM Album A JOIN Track T ON A.AlbumId = T.AlbumId
               JOIN Artist AR ON A.ArtistId = AR.ArtistId 
  GROUP BY A.AlbumId;
  • Filtrado por grupos (seleccionar grupos con condiciones)
  SELECT AR.Name AS Artista, AS Album, COUNT(*) AS Canciones, SUM(UnitPrice) AS Precio
  FROM Album A JOIN Track T ON A.AlbumId = T.AlbumId 
  GROUP BY A.AlbumId
  HAVING Canciones > 6; 

2.5.7 Subconsultas (subqueries)

  • Subqueries en la cláusula SELECT:

    • La consulta debe devolver una única columna, y típicamente un único valor
  SELECT T.Name, (SELECT COUNT(*) 
                  FROM Track T2 
                  WHERE T2.GenreId = T.GenreId) AS Canciones 
  FROM Track T JOIN Genre G ON T.GenreId = G.GenreId; 
  • Observación: en una subquery se puede hacer referencia a columnas de la consulta externa.

  • Subqueries en la cláusula WHERE / HAVING:

  SELECT T.Name, T.Milliseconds 
  FROM Track T 
  WHERE T.Milliseconds > (SELECT AVG(Milliseconds) FROM Track);  
  • Subqueries en la cláusula FROM:
  SELECT T.Song, G.Name 
  FROM Genre G JOIN (SELECT Name AS Song, GenreId as Id 
                     FROM Track) AS T 
               ON Id = G.GenreId 

2.5.8 Operaciones con conjuntos de resultados

  Query1 
  { UNION [ ALL ] | INTERSECT | EXCEPT } 
  Query2 
  • Query1 y Query2 deben devolver el mismo número de columnas, pero no necesariamente el mismo tipo de dato. Elimina filas duplicadas.
  • Unión: Resultados existentes en alguna consulta (eq. OR)
  • Intersección: Resultados existentes en ambas consultas (eq. AND)
  • Diferencia (Except): Resultados existentes en Query1 pero no en Query2 (eq. MINUS)
  • Cláusula UNION ALL: Elimina la restricción de filas duplicadas y muestra todo