miércoles, 17 de febrero de 2016

Empezando con la Sentencia SELECT

Este post trata dos de las principales cláusulas de consulta, FROM y SELECT.

Utilizando las Cláusulas FROM y SELECT

Las cláusulas FROM y SELECT son las dos cláusulas principales que aparecen en casi todas las consultas que recuperan datos. Este post explica el propósito de estas cláusulas, cómo usarlas, y las mejores prácticas asociadas con ellas.

La Cláusula FROM

De acuerdo con el procesamiento de consultas lógico, la cláusula FROM es la primera cláusula a ser evaluada lógicamente en una consulta SELECT. La cláusula FROM tiene dos roles principales:
·         Es la cláusula donde se indican las tablas que desea consultar.
·         Es la cláusula donde se pueden aplicar operadores de tabla como joins a las tablas de entrada.
Este post se enfoca en el primer rol.
Como ejemplo básico, suponga que está conectado a la base de datos de ejemplo TSQL2012, la siguiente consulta utiliza la cláusula FROM para especificar que HR.Employees es la tabla que está siendo consultada.
SELECT empid, firstname, lastname
FROM HR.Employees;
Observe el uso del nombre de dos partes para referirse a la tabla. La primera parte (HR) es el nombre del esquema y la segunda parte (Employees) es el nombre de la tabla. En algunos casos, T-SQL soporta omitir el nombre del esquema, como en FROM Employees, en cuyo caso se utiliza un proceso de resolución implícita de nombres de esquema. Se considera una buena práctica siempre indicar explícitamente el nombre del esquema. Esta práctica puede evitar el terminar con un nombre de esquema que no pretendía utilizar, y también puede eliminar el costo involucrado en el proceso de resolución implícita, aunque este costo sea mínimo.
En la cláusula FROM, puede dar alias a las tablas consultadas con sus nombres elegidos. Puede usar la forma <tabla> <alias>, como en HR.Employees E, o <tabla> AS <alias>, como en HR.Employees AS E. La última forma es más legible. Cuando usa alias, la convención es usar nombres cortos, típicamente una letra que de alguna manera sea un indicativo de la tabla consultada, como E para Employees.
Note que si asigna un alias a una tabla, básicamente, renombra la tabla para la duración de la consulta. El nombre de la tabla original ya no es visible; sólo el alias. Normalmente, puede colocar un prefijo a un nombre de columna para referirse a él en una consulta con el nombre de la tabla, como en Employees.empid. Sin embargo, si le diste un alias a la tabla Employees como E, la referencia Employees.empid ya no es válida; tiene que utilizar E.empid, como demuestra el siguiente ejemplo.
SELECT E.empid, firstname, lastname
FROM HR.Employees AS E;
Si intenta ejecutar este código utilizando el nombre de tabla completo como prefijo de la columna, el código fallará.

La Cláusula SELECT

La cláusula SELECT de una consulta tiene dos roles principales:
·    Evalúa las expresiones que definen los atributos en el resultado de la consulta, asignándoles alias, si es necesario.
·         Usando una cláusula DISTINCT, puede eliminar las filas duplicadas en el resultado si es necesario.
Empezará con el primer rol. Tome la consulta siguiente como un ejemplo.
SELECT empid, firstname, lastname
FROM HR.Employees;
La cláusula FROM indica que la tabla HR.Employees es la tabla de entrada de la consulta. La cláusula SELECT entonces proyecta sólo tres de los atributos de entrada como los atributos retornados en el resultado de la consulta.
T-SQL soporta utilizar un asterisco (*) como una alternativa para listar todos los atributos de las tablas de entrada, pero esto es considerado una mala práctica por varias razones. A menudo, necesita retornar sólo un subconjunto de los atributos de entrada, y el usar un * es sólo una cuestión de pereza. Al retornar más atributos de los que realmente necesita, puede impedir que SQL Server utilice lo que normalmente es considerado como índices cubiertos, con respecto a un conjunto interesante de atributos. También envía más datos de los que necesita la red, y esto puede tener un impacto negativo en el rendimiento del sistema. Además, la definición de la tabla originaria podría cambiar con el tiempo; incluso, cuando la consulta fue inicialmente escrita, * realmente representó todos los atributos que necesitaba; podría no ser el caso en un punto posterior en el tiempo. Por estas y otras razones, es considerado una buena práctica siempre listar explícitamente los atributos que necesita.
En la cláusula SELECT, puede asignar sus propios alias a las expresiones que definen los atributos de resultado. Hay un número de formatos soportados de alias: <expresión> AS <alias> como en empid AS employeeid, <expresión> <alias> como en employeeid empid y <alias> = <expresión> como en employeeid = empid.
Un Método Preferido
Nosotros preferimos utilizar la primera forma con la cláusula AS, porque es estándar y resulta más fácil de leer. La segunda forma es ilegible y hace que sea difícil detectar un cierto error en el código.
Considere la siguiente consulta.
SELECT empid, firstname lastname
FROM HR.Employees;
El desarrollador quien es autor de la consulta intentó retornar los atributos empid, firstname, y lastname, pero olvidó indicar la coma entre firstname y lastname. La consulta no falla; en cambio, devuelve el siguiente resultado.
empid        lastname
----------- ----------
1            Sara
2            Don
3            Judy
...
Aunque no es la intención del autor, SQL Server interpreta la solicitud como la asignación del alias lastname al atributo firstname en lugar de retornar ambos. Si ha utilizado las expresiones de alias con la forma de espacio como una práctica común, le será más difícil detectar tales errores.
Regresando al alias de atributo intencional, hay dos usos principales para estos. Uno es renombrarlo, cuando necesita que el atributo resultado sea nombrado de una manera diferente que el atributo de origen, por ejemplo, si necesita nombrar el atributo resultado a employeeid en lugar de empid, de la siguiente manera.
SELECT empid AS employeeid, firstname, lastname
FROM HR.Employees;
Otro uso es asignar un nombre a un atributo que resulta de una expresión que de otra forma quedaría sin nombre. Por ejemplo, supongamos que necesita generar un atributo resultado a partir de una expresión que concatena el atributo firstname, un espacio, y el atributo lastname. Utilice la siguiente consulta.
SELECT empid, firstname + N' ' + lastname
FROM HR.Employees;
Obtendrá un resultado no relacional, porque el atributo resultado no tiene nombre.
empid
----------- -------------------------------
1            Sara Davis
2            Don Funk
3            Judy Lew
...
Al colocar alias a la expresión, se asigna un nombre al atributo resultado, haciendo al resultado de la consulta relacional, de la siguiente manera.
SELECT empid, firstname + N' ' + lastname AS nombrecompleto
FROM HR.Employees;
He aquí una forma abreviada del resultado de esta consulta.
empid        nombrecompleto
----------- -------------------------------
1            Sara Davis
2            Don Funk
3            Judy Lew
...
Recuerde que si los duplicados son posibles en el resultado, T-SQL no tratará de eliminarlos a menos que se le instruya. Un resultado con duplicados es considerado no relacional, porque las relaciones, siendo conjuntos, no suponen tener duplicados. Por lo tanto, si los duplicados son posibles en el resultado, y desea eliminarlos con el fin de devolver un resultado relacional, puede hacerlo añadiendo una cláusula DISTINCT, como en la siguiente.
SELECT DISTINCT country, region, city
FROM HR.Employees;
La tabla HR.Employees tiene nueve filas pero cinco localizaciones distintas; por lo tanto, la salida de esta consulta tiene cinco filas.
country             region       city
--------------- --------------- ---------------
UK                  NULL         London
USA                 WA           Kirkland
USA                 WA           Redmond
USA                 WA           Seattle
USA                 WA           Tacoma
Hay una diferencia interesante entre el SQL estándar y el T-SQL en términos de requisitos de consulta SELECT mínimos. De acuerdo al SQL estándar, una consulta SELECT debe tener las cláusulas FROM y SELECT como mínimo. A la inversa, T-SQL soporta una consulta SELECT con sólo una cláusula SELECT y sin una cláusula FROM. Dicha consulta es como si se emitiera sobre una tabla imaginaria que tiene sólo una fila. Por ejemplo, la siguiente consulta no es válida según el SQL estándar, pero es válida de acuerdo a T-SQL.
SELECT 10 AS col1, 'ABC' AS col2;
La salida de esta consulta es una única fila con atributos resultado de las expresiones con nombres asignados utilizando los alias.
col1         col2
----------- ----
10           ABC

Delimitando Identificadores

Cuando se refiere a identificadores de atributos, esquemas, tablas y otros objetos, hay casos en los cuales es necesario utilizar delimitadores versus los casos en el cual el uso de delimitadores es opcional. T-SQL soporta tanto una forma estándar para delimitar identificadores utilizando comillas dobles, como en "Sales"."Orders", así como una forma propietaria utilizando corchetes, como en [Sales].[Orders].
Cuando el identificador es "regular", la delimitación es opcional. En un identificador regular, el identificador cumple con las reglas para el formato de identificadores. Las reglas dicen que el primer carácter debe ser una letra entre el rango de la A hasta la Z (minúsculas o mayúsculas), un guión bajo (_), un símbolo de arroba (@), o el símbolo de número (#). Los siguientes caracteres pueden incluir letras, números decimales, arroba, signo de dólar ($), signo de número o guión bajo. El identificador no puede ser una palabra clave reservada en T-SQL, no puede tener espacios incrustados, y no debe incluir caracteres suplementarios.
Un identificador que no cumpla con estas reglas debe ser delimitado. Por ejemplo, un atributo llamado 2006 es considerado un identificador irregular, ya que comienza con un dígito, y por lo tanto, debe ser delimitado como "2006" o [2006]. Un identificador regular como y2006 puede ser referenciado sin delimitadores simplemente como y2006, o puede ser opcional con delimitadores. Podría preferir no delimitar los identificadores regulares porque los delimitadores tienden a confundir el código.

Ejercicio 1: Escribir una Consulta Simple y Usar Alias en Tablas

En este ejercicio, practica el uso de las cláusulas FROM y SELECT, incluyendo el uso de los alias de tabla.
1.    Abra el SSMS y conéctese a la base de datos de ejemplo TSQL2012.
2.    Para practicar la escritura de una consulta sencilla que utiliza las cláusulas FROM y SELECT, escriba la siguiente consulta y ejecútela.
USE TSQL2012;
SELECT shipperid, companyname, phone
FROM Sales.Shippers;
La sentencia USE asegura de que esté conectado a la base de datos de destino TSQL2012. La cláusula FROM indica que la tabla Sales.Shippers es la tabla consultada, y la cláusula SELECT proyecta los atributos shipperid, companyname, y phone de esta tabla. Aquí está el resultado de la consulta.
shipperid  companyname     phone
---------- -------------- ---------------
1          Shipper GVSUA   (503) 555-0137
2          Shipper ETYNR   (425) 555-0136
3          Shipper ZHISN   (415) 555-0138
3.    Si hay más de una tabla involucrada en la consulta y otra tabla tiene un atributo llamado shipperid, necesitaría un prefijo en el atributo shipperid con el nombre de la tabla, como en Shippers.shipperid. Para abreviar, puede dar un alias a la tabla con un nombre más corto, como S y, entonces, referirse al atributo como S.shipperid. He aquí un ejemplo de alias de tabla y dar un prefijo al atributo con el nuevo nombre de tabla.
SELECT S.shipperid, companyname, phone
FROM Sales.Shippers AS S;

Ejercicio 2: Usar Alias de Columna e Identificadores Delimitados

En este ejercicio, practicará el uso de alias de columnas, incluyendo el uso de identificadores delimitados. Como punto de partida, utiliza la consulta del paso 3 del ejercicio anterior.
1.    Suponga que desea renombrar el atributo resultado phone a phone number. He aquí un intento de poner alias al atributo con identificador phone number sin delimitadores.
SELECT S.shipperid, companyname, phone AS phone number
FROM Sales.Shippers AS S;
2.    Este código falla porque phone number no es un identificador regular, y por lo tanto tiene que estar delimitado, de la siguiente manera.
SELECT S.shipperid, companyname, phone AS [phone number]
FROM Sales.Shippers AS S;

3.    Recuerde que T-SQL soporta tanto una forma propietaria para delimitar identificadores utilizando corchetes y la forma estándar utilizando comillas dobles, como en "phone number".

1 comentario: