Sentencia SELECT SQL hacer consultas con ejemplos

La declaración SELECT está en el corazón de la mayoría de las consultas SQL. Define qué conjunto de resultados debe devolver la consulta y casi siempre se usa junto con la cláusula FROM, que define qué partes de la base de datos deben consultarse.

Uso del carácter comodín * para seleccionar todas las columnas de una consulta.

Considere una base de datos con las siguientes dos tablas.

Tabla de empleados (Employees):

IdentificaciónFNombreLNombreID de departamento
1JaimeHerrero3
2JohnJohnson4

Tabla de departamentos (Departments):

IdentificaciónNombre
1Ventas
2Marketing
3Finanzas
4ESO

Declaración SELECT simple

El carácter comodín * es utilizado para seleccionar todas las columnas disponibles en una tabla.

Cuando se utiliza como sustituto de los nombres explícitos de las columnas, devuelve todas las columnas de todas las tablas de las que una consulta está seleccionando FROM. Este efecto se aplica a todas las tablas a las que la consulta accede a través de sus cláusulas JOIN.

Considere la siguiente consulta:

SELECT * FROM Employees

Devolverá todos los campos de todas las filas de la tabla Employees:

IdentificaciónFNombreLNombreID de departamento
1JaimeHerrero3
2JohnJohnson4

Notación de puntos

Para seleccionar todos los valores de una tabla específica, el carácter comodín se puede aplicar a la tabla con notación de puntos .

Considere la siguiente consulta:

SELECT 
    Employees.*, 
    Departments.Name
FROM 
    Employees
JOIN 
    Departments 
    ON Departments.Id = Employees.DeptId

Esto devolverá un conjunto de datos con todos los campos de la tabla Employee, seguido solo por el campo Name de la tabla Departments:

|Id|FName|LName|DeptId|Name |---|---|---|--- |1|James|Smith|3|Finance |2|John|Johnson|4|IT

Advertencias de uso

En general, se recomienda * evitar el uso en el código de producción siempre que sea posible, ya que puede causar una serie de problemas potenciales, que incluyen:

  1. Exceso de IO, carga de red, uso de memoria, etc., debido a que el motor de la base de datos lee datos que no son necesarios y los transmite al código del front-end. Esto es especialmente preocupante cuando hay campos grandes, como los utilizados para almacenar notas largas o archivos adjuntos.
  2. Más carga de IO si la base de datos necesita enviar los resultados internos al disco como parte del procesamiento de una consulta más compleja que SELECT <columns> FROM <table>.
  3. Procesamiento extra (y/o aún más IO) si algunas de las columnas innecesarias son:
  4. columnas computadas en las bases de datos que las soportan
  5. en el caso de la selección de una vista, columnas de una tabla/vista que el optimizador de consultas podría optimizar de otro modo
  6. La posibilidad de que se produzcan errores inesperados si se añaden columnas a las tablas y vistas más adelante que den lugar a nombres de columna ambiguos. Por ejemplo, SELECT * FROM orders JOIN people ON people.id = orders.personid ORDER BY displayname – si se añade una columna llamada displayname a la tabla orders para permitir a los usuarios dar a sus pedidos nombres significativos para futuras referencias, entonces el nombre de la columna aparecerá dos veces en la salida, por lo que la cláusula ORDER BY será ambigua, lo que puede causar errores («nombre de columna ambiguo» en las versiones recientes de MS SQL Server), y si no en este ejemplo su código de aplicación podría empezar a mostrar el nombre del pedido donde se pretende el nombre de la persona porque la nueva columna es la primera de ese nombre devuelta, y así sucesivamente.

¿Cuándo se puede usar *, teniendo en cuenta la advertencia anterior?

Si bien es mejor evitarlo en el código de producción, usar * está bien como abreviatura cuando se realizan consultas manuales en la base de datos para investigación o trabajo de prototipo.

A veces, las decisiones de diseño en su aplicación lo hacen inevitable (en tales circunstancias, prefiera tablealias.* en lugar de sólo * cuando sea posible).

Cuando se usa EXISTS, como SELECT A.col1, A.Col2 FROM A WHERE EXISTS (SELECT * FROM B where A.ID = B.A_ID), no devolvemos ningún dato de B. Por lo tanto, una combinación es innecesaria y el motor sabe que no se devolverán valores de B, por lo que no se afecta el rendimiento por usar *. Del mismo modo COUNT(*), está bien, ya que tampoco devuelve ninguna de las columnas, por lo que solo necesita leer y procesar aquellas que se usan para fines de filtrado.

SELECT utilizando alias de columnas

Los alias de columna se utilizan principalmente para acortar el código y hacer que los nombres de las columnas sean más legibles.

El código se acorta, ya que se pueden evitar los nombres largos de las tablas y la identificación innecesaria de las columnas (por ejemplo, puede haber 2 ID en la tabla, pero sólo se utiliza uno en la sentencia). Junto con los alias de tabla, esto le permite utilizar nombres descriptivos más largos en la estructura de su base de datos, al tiempo que mantiene concisas las consultas sobre dicha estructura.

Además, a veces son necesarios, por ejemplo en las vistas, para nombrar las salidas calculadas.

Creando alias compatible con todas las versiones de SQL

Los alias se pueden crear en todas las versiones de SQL usando comillas dobles (").

SELECT 
    FName AS "First Name", 
    MName AS "Middle Name",
    LName AS "Last Name"
FROM Employees  

Diferentes versiones de SQL

Puede usar comillas simples ('), comillas dobles (") y corchetes ([]) para crear un alias en Microsoft SQL Server.

SELECT 
    FName AS "First Name", 
    MName AS 'Middle Name',
    LName AS [Last Name]
FROM Employees  

Ambos resultarán en:

First NameMiddle NameLast Name
JaimeJohnHerrero
JohnJaimeJohnson
MiguelmarcusWilliams

Esta declaración devolverá columnas FNameLName con un nombre dado (un alias). Esto se logra usando el operador AS seguido del nombre del alias, o simplemente escribiendo alias directamente después del nombre de la columna. Esto significa que la siguiente consulta tiene el mismo resultado que la anterior.

SELECT 
    FName "First Name", 
    MName "Middle Name",
    LName "Last Name"
FROM Employees 
First NameMiddle NameLast Name
JaimeJohnHerrero
JohnJaimeJohnson
MiguelmarcusWilliams

Sin embargo, la versión explícita (es decir, usando el operador AS ) es más legible.

Si el alias tiene una sola palabra que no es una palabra reservada, podemos escribirla sin comillas simples, comillas dobles o corchetes:

SELECT 
    FName AS FirstName, 
    LName AS LastName
FROM Employees  
Primer nombreApellido
JaimeHerrero
JohnJohnson
MiguelWilliams

Otra variación disponible en MS SQL Server, entre otras, es <alias> = <column-or-calculation>, por ejemplo:

SELECT FullName = FirstName + ' ' + LastName, 
       Addr1    = FullStreetAddress,
       Addr2    = TownName
FROM CustomerDetails  

que es equivalente a:

SELECT FirstName + ' ' + LastName As FullName
       FullStreetAddress          As Addr1,
       TownName                   As Addr2
FROM CustomerDetails  

Ambos resultarán en:

FullNameAddr1Addr2
james smith123 cualquier calleciudadvilla
Juan Johnson668 mi caminoCualquier pueblo
miguel williams999 High End DrWilliamsburgh

Algunos encuentran que usar = en lugar de As más fácil de leer, aunque muchos no recomiendan este formato, principalmente porque no es estándar, por lo que no es ampliamente compatible con todas las bases de datos. Puede causar confusión con otros usos del caracter =.

En Todas las versiones de SQL Usando Palabras reservadas como alias

Además, si necesita usar palabras reservadas, puede usar corchetes o comillas para escapar:

SELECT
    FName as "SELECT",
    MName as "FROM",
    LName as "WHERE"
FROM Employees

En Diferentes versiones de SQL Usando Palabras reservadas como alias

Del mismo modo, puede escapar palabras clave en MSSQL con todos los enfoques diferentes:

SELECT 
    FName AS "SELECT", 
    MName AS 'FROM',
    LName AS [WHERE]
FROM Employees  
SELECTFROMWHERE
JaimeJohnHerrero
JohnJaimeJohnson
MiguelmarcusWilliams

Además, se puede usar un alias de columna en cualquiera de las cláusulas finales de la misma consulta, como ORDER BY:

SELECT 
    FName AS FirstName, 
    LName AS LastName
FROM 
    Employees 
ORDER BY 
    LastName DESC

Sin embargo, no puede utilizar sin escapar las palabras reservadas para crear un alias a partir de estas palabras reservadas ( SELECTFROM). Esto causará numerosos errores en la ejecución.

SELECT
    FName AS SELECT,
    LName AS FROM
FROM 
    Employees
ORDER BY 
    LastName DESC

Seleccionar columnas individuales

SELECT 
    PhoneNumber, 
    Email, 
    PreferredContact 
FROM Customers

Esta instrucción devolverá las columnas PhoneNumberEmailPreferredContact de todas las filas de la tabla Customers. Además, las columnas se devolverán en la secuencia en que aparecen en la cláusula SELECT.

El resultado será:

PhoneNumberEmailPreferredContact
3347927472[email protected]TELÉFONO
2137921892[email protected]EMAIL
NULO[email protected]EMAIL

Si se unen varias tablas, puede seleccionar columnas de tablas específicas especificando el nombre de la tabla antes del nombre de la columna: [table_name].[column_name]

SELECT 
    Customers.PhoneNumber, 
    Customers.Email, 
    Customers.PreferredContact,
    Orders.Id AS OrderId
FROM 
    Customers
LEFT JOIN 
    Orders ON Orders.CustomerId = Customers.Id

AS OrderId significa que el campo Id de la tabla Orders se devolverá como una columna denominada OrderId.

Para evitar el uso de nombres de tabla largos, puede usar alias de tabla. Esto mitiga el dolor de escribir nombres de tabla largos para cada campo que seleccione en las uniones. Si está realizando una unión automática (una unión entre dos instancias de la misma tabla), debe usar alias de tabla para distinguir sus tablas. Podemos escribir un alias de tabla como Customers cCustomers AS c. Aquí c funciona como un alias para Customers y podemos seleccionar digamos Email así: c.Email.

SELECT 
    c.PhoneNumber, 
    c.Email, 
    c.PreferredContact,
    o.Id AS OrderId
FROM 
    Customers c
LEFT JOIN 
    Orders o ON o.CustomerId = c.Id

Selecciónar un número específico de registros

El estándar SQL 2008 define la cláusula FETCH FIRST para limitar el número de registros devueltos.

SELECT Id, ProductName, UnitPrice, Package 
FROM Product 
ORDER BY UnitPrice DESC
FETCH FIRST 10 ROWS ONLY

Este estándar solo es compatible con versiones recientes de algunos RDBMS. La sintaxis no estándar específica de cada proveedor se proporciona en otros sistemas. Progress OpenEdge 11.x también es compatible con la sintaxis FETCH FIRST <n> ROWS ONLY.

Además, OFFSET <m> ROWS antes de FETCH FIRST <n> ROWS ONLY permite saltar filas antes de obtener filas. Esto es utilizado por ejemplo en las paginaciones cuando se necesita tener un margen devolviendo el mismo número de registros pero no los mismos, donde la página 2 necesita tener una margen y así cada nueva página de resultados.

SELECT Id, ProductName, UnitPrice, Package 
FROM Product 
ORDER BY UnitPrice DESC
OFFSET 5 ROWS
FETCH FIRST 10 ROWS ONLY

La siguiente consulta es compatible con SQL Server y MS Access:

SELECT TOP 10 Id, ProductName, UnitPrice, Package
FROM Product
ORDER BY UnitPrice DESC

Para hacer lo mismo en MySQL o PostgreSQL se debe utilizar la palabra clave LIMIT:

SELECT Id, ProductName, UnitPrice, Package
FROM Product
ORDER BY UnitPrice DESC
LIMIT 10

En Oracle se puede hacer lo mismo con ROWNUM:

SELECT Id, ProductName, UnitPrice, Package
FROM Product
WHERE ROWNUM <= 10
ORDER BY UnitPrice DESC

Resultados : 10 registros.

Id    ProductName               UnitPrice             Package
38    Côte de Blaye             263.50                12 - 75 cl bottles
29    Thüringer Rostbratwurst   123.79                50 bags x 30 sausgs.
9    Mishi Kobe Niku            97.00                 18 - 500 g pkgs.
20    Sir Rodney's Marmalade    81.00                 30 gift boxes
18    Carnarvon Tigers          62.50                 16 kg pkg.
59    Raclette Courdavault      55.00                 5 kg pkg.
51    Manjimup Dried Apples     53.00                 50 - 300 g pkgs.
62    Tarte au sucre            49.30                 48 pies
43    Ipoh Coffee               46.00                 16 - 500 g tins
28    Rössle Sauerkraut         45.60                 25 - 825 g cans


Matices sobre el proveedor:

Es importante tener en cuenta que TOP en Microsoft SQL opera después de la cláusula WHERE y devolverá la cantidad especificada de resultados si existen en cualquier parte de la tabla, mientras que ROWNUM funciona como parte de la cláusula WHERE, por lo que si no existen otras condiciones en la cantidad especificada de filas al comienzo de la tabla, obtendrá cero resultados cuando podría encontrar otros.

Usando SELECT con la condición WHERE

La sintaxis básica de SELECT con la cláusula WHERE es:

SELECT column1, column2, columnN
FROM table_name
WHERE [condition]

La [condition] puede ser cualquier expresión SQL, especificada mediante operadores lógicos o de comparación como >, <, =, <>, >=, <=, LIKE, NOT, IN, BETWEEN, etc.

La siguiente declaración devuelve todas las columnas de la tabla ‘Cars’ donde la columna de status es ‘READY’:

SELECT * FROM Cars WHERE status = 'READY'

Usando la sentencia SELECT CASE

Cuando los resultados necesitan tener alguna lógica aplicada ‘sobre la marcha’, se puede usar la instrucción CASE para implementarla.

SELECT CASE WHEN Col1 < 50 THEN 'under' ELSE 'over' END threshold
FROM TableName 

SELECT CASE también pueden ser encadenado

SELECT 
    CASE WHEN Col1 < 50 THEN 'under' 
         WHEN Col1 > 50 AND Col1 <100 THEN 'between' 
         ELSE 'over' 
    END threshold
FROM TableName 

También se puede tener una declaración CASE dentro de otra declaración CASE.

SELECT 
    CASE WHEN Col1 < 50 THEN 'under' 
         ELSE 
            CASE WHEN Col1 > 50 AND Col1 <100 THEN Col1 
            ELSE 'over' END 
    END threshold
FROM TableName 

Seleccionar columnas que llevan el nombre de una palabras clave reservada

Cuando un nombre de columna coincide con una palabra clave reservada, SQL estándar requiere que lo escriba entre comillas dobles:

SELECT 
    "ORDER",
    ID 
FROM ORDERS

Tenga en cuenta que el nombre de la columna distinge entre mayúsculas y minúsculas.

Algunas DBMSes tienen sus propias formas de citar nombres. Por ejemplo, SQL Server usa corchetes para este propósito:

SELECT 
    [Order],
    ID 
FROM ORDERS

mientras que MySQL (y MariaDB) por defecto usan acentos graves llamados backticks:

SELECT 
    `Order`,
    id 
FROM orders


Seleccionar una tabla usando un alias

SELECT e.Fname, e.LName 
FROM Employees e

La tabla Employees recibe el alias ‘e’ directamente después del nombre de la tabla. Esto ayuda a eliminar la ambigüedad en escenarios en los que varias tablas tienen el mismo nombre de campo y debe especificar de qué tabla desea obtener datos.

SELECT e.Fname, e.LName, m.Fname AS ManagerFirstName 
FROM Employees e 
    JOIN Managers m ON e.ManagerId = m.Id

Tenga en cuenta que una vez que define un alias, ya no puede usar el nombre de la tabla canónica. es decir,

SELECT e.Fname, Employees.LName, m.Fname AS ManagerFirstName 
FROM Employees e 
JOIN Managers m ON e.ManagerId = m.Id

arrojaría un error.

Vale la pena señalar que los alias de tabla, más formalmente ‘variables de rango’, se introdujeron en el lenguaje SQL para resolver el problema de las columnas duplicadas causadas por INNER JOIN. El estándar SQL de 1992 corrigió esta falla de diseño anterior mediante la introducción NATURAL JOIN (implementada en mySQL, PostgreSQL y Oracle pero aún no en SQL Server), cuyo resultado nunca tiene nombres de columna duplicados. El ejemplo anterior es interesante porque las tablas se unen en columnas con nombres diferentes ( IdManagerId), pero se supone que no deben unirse en las columnas con el mismo nombre ( LNameFName), lo que requiere que se realice el cambio de nombre de las columnas antes de la unión:

SELECT Fname, LName, ManagerFirstName 
FROM Employees
     NATURAL JOIN
     ( SELECT Id AS ManagerId, Fname AS ManagerFirstName
       FROM Managers ) m;

Tenga en cuenta que aunque se debe declarar una variable de alias/rango para la tabla derivada (de lo contrario, SQL arrojará un error), nunca tiene sentido usarla en la consulta.

Ordenar los Resultados en una Selección con ORDER BY

SELECT * FROM Employees ORDER BY LName

Esta declaración devolverá todas las columnas de la tabla Employees Ordenados por Lname.

IdFNameLnamePhoneNumber
2JohnJohnson2468101214
1JaimeHerrero1234567890
3MiguelWilliams1357911131
SELECT * FROM Employees ORDER BY LName DESC

O

SELECT * FROM Employees ORDER BY LName ASC

Esta instrucción cambia explicitamente la dirección de clasificación. También se pueden especificar varias columnas de clasificación. Por ejemplo:

SELECT * FROM Employees ORDER BY LName ASC, FName ASC

Este ejemplo ordenará los resultados primero por LName y luego, para los registros que tienen el mismo LName, ordene por FName. Esto le dará un resultado similar al que encontraría en una guía telefónica.

Para evitar tener que volver a escribir el nombre de la columna en la cláusula ORDER BY, es posible utilizar en su lugar el número de la columna. Tenga en cuenta que los números de columna comienzan desde 1, donde en número 3 hace referencia a la columna Lname.

SELECT Id, FName, LName, PhoneNumber FROM Employees ORDER BY 3

También puede insertar una declaración CASE en ORDER BY.

SELECT Id, FName, LName, PhoneNumber FROM Employees ORDER BY CASE WHEN LName='Jones` THEN 0 ELSE 1 END ASC

Esto ordenará sus resultados para tener todos los registros con LName«Jones» en la parte superior.

Selección con funciones integradas en SQL

Función AVG SQL para obtener el promedio

SELECT AVG(Salary) FROM Employees
SELECT AVG(Salary) FROM Employees where DepartmentId = 1

Si el empleado (de employee) está categorizado con varios departamentos y queremos encontrar el salario promedio para cada departamento, entonces podemos usar la siguiente consulta.

SELECT AVG(Salary) FROM Employees GROUP BY DepartmentId

Función SQL MIN para obtener el valor Mínimo

SELECT MIN(Salary) FROM Employees

Función MAX SQL para obtener el valor Máximo

SELECT MAX(Salary) FROM Employees

Función COUNT SQL para Contar el número de resultados

SELECT COUNT(*) FROM Employees
SELECT COUNT(*) FROM Employees where ManagerId IS NOT NULL
Select COUNT(ManagerId) from Employees
Select COUNT(DISTINCT DepartmentId) from Employees

Función SUM SQL para Suma de los resultados

SELECT SUM(Salary) FROM Employees


Seleccionar una tabla sin causar un bloqueo

A veces, cuando las tablas se usan principalmente (o solo) para lecturas, la indexación ya no ayuda y cada bit cuenta, uno puede usar selecciones sin LOCK para mejorar el rendimiento.

SQL Server

SELECT * FROM TableName WITH (nolock)

MySQL

SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
SELECT * FROM TableName;
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;

Oracle

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
SELECT * FROM TableName;

DB2

SELECT * FROM TableName WITH UR;

donde UR significa «lectura no confirmada».

Si se usa en una tabla que tiene modificaciones de registro en curso, puede tener resultados impredecibles.

Seleccionar con una condición de multiples valores usando IN

SELECT * FROM Cars  WHERE status IN ( 'Waiting', 'Working' )

Esto es semánticamente equivalente a

SELECT * FROM Cars  WHERE ( status = 'Waiting' OR status = 'Working' )

Es decir value IN ( <value list> ), es una abreviatura de disyunción (lógica OR).

Obtener el resultado agregado de los grupos de filas con Group By

Contar filas en función de un valor de columna específico:

SELECT category, COUNT(*) AS item_count
FROM item
GROUP BY category;

Obtener el ingreso promedio por departamento:

SELECT department, AVG(income)
FROM employees
GROUP BY department;

Lo importante es seleccionar solo las columnas especificadas en el GROUP BY o usado con funciones agregadas.

Donde La cláusula WHERE también se puede usar con GROUP BY, pero WHERE filtra los registros antes de que se realice cualquier agrupación:

SELECT department, AVG(income)
FROM employees
WHERE department <> 'ACCOUNTING'
GROUP BY department;

Si necesita filtrar los resultados después de que se haya realizado la agrupación, por ejemplo, para ver solo los departamentos cuyo ingreso promedio es superior a 1000, debe usar la cláusula HAVING:

SELECT department, AVG(income)
FROM employees
WHERE department <> 'ACCOUNTING'
GROUP BY department
HAVING avg(income) > 1000;

Cómo tener más de una condición en un SELECT

La palabra clave AND se utiliza para agregar más condiciones a la consulta.

NameAgeGender
Sam18M
John21M
Bob22M
Mary23F
SELECT name FROM persons WHERE gender = 'M' AND age > 20;

Esto devolverá:

Name
John
Bob

usando palabra clave OR

SELECT name FROM persons WHERE gender = 'M' OR age < 20;

Esto devolverá:

name
Sam
John
Bob

Estas palabras clave se pueden combinar para permitir combinaciones de criterios más complejas:

SELECT name
FROM persons
WHERE (gender = 'M' AND age < 20)
   OR (gender = 'F' AND age > 20);

Esto devolverá:

name
Sam
Mary

Seleccionar filas de varias tablas con producto cruzado en SQL

SELECT *
FROM
    table1,
    table2
SELECT
    table1.column1,
    table1.column2,
    table2.column1
FROM
    table1,
    table2

Esto se llama producto cruzado en SQL, es lo mismo que el producto cruzado en conjuntos

Estas declaraciones devuelven las columnas seleccionadas de varias tablas en una consulta.

No existe una relación específica entre las columnas devueltas de cada tabla.

Selección con nulos

SELECT Name FROM Customers WHERE PhoneNumber IS NULL

La selección con nulos toma una sintaxis diferente. No use =, use IS NULLIS NOT NULL en su lugar ya que un nulo no es = a otro nulo.

Seleccionar distintos o solo valores únicos

SELECT DISTINCT ContinentCode
FROM Countries;

Esta consulta devolverá todos los valores DISTINCT (únicos, diferentes) de la columna ContinentCode de tabla Countries

ContinentCode
OC
EU
AS
NA
AF

Sintaxis

SELECT [DISTINCT] [column1] [, [column2] ... ]
FROM [table]
[ WHERE condition ]
[ GROUP BY [column1] [, [column2] ... ]

[ HAVING [column1] [, [column2] ... ] [ ORDER BY ASC | DESC ]

Observaciones

SELECT determina qué datos de las columnas deben devolverse y en qué orden desde (FROM) una tabla dada (dado que coinciden con los otros requisitos de su consulta específicamente – donde y teniendo filtros y uniones).

SELECT Name, SerialNumber
FROM ArmyInfo

Solo devolverá resultados de las columnas NameSerial Number, pero no de la columna llamada Rank, por ejemplo

SELECT *
FROM ArmyInfo

Indica que se devolverán todas las columnas. Sin embargo, tenga en cuenta que es una mala práctica SELECT *, ya que literalmente está devolviendo todas las columnas de una tabla.