FROM (Transact-SQL)

Especifica las tablas, vistas, tablas derivadas y tablas combinadas que se utilizan en las instrucciones DELETE, SELECT y UPDATE. En la instrucción SELECT, la cláusula FROM es necesaria excepto cuando la lista de selección solo contiene constantes, variables y expresiones aritméticas (sin nombres de columna).

Icono de vínculo a temasConvenciones de sintaxis de Transact-SQL

Sintaxis

[ FROM { <table_source> } [ ,...n ] ] 
<table_source> ::= 
{
        table_or_view_name [ [ AS ] table_alias ] [ <tablesample_clause> ] 
        [ WITH ( < table_hint > [ [ , ]...n ] ) ] 
    | rowset_function [ [ AS ] table_alias ] 
        [ ( bulk_column_alias [ ,...n ] ) ] 
        | user_defined_function [ [ AS ] table_alias ] ]
    | OPENXML <openxml_clause> 
    | derived_table [ AS ] table_alias [ ( column_alias [ ,...n ] ) ] 
    | <joined_table> 
    | <pivoted_table> 
    | <unpivoted_table>
      | @variable [ [ AS ] table_alias ]
        | @variable.function_call ( expression [ ,...n ] ) [ [ AS ] table_alias ] [ (column_alias [ ,...n ] ) ]
}
<tablesample_clause> ::=
    TABLESAMPLE [SYSTEM] ( sample_number [ PERCENT | ROWS ] ) 
        [ REPEATABLE ( repeat_seed ) ] 

<joined_table> ::= 
{
    <table_source> <join_type> <table_source> ON <search_condition> 
    | <table_source> CROSS JOIN <table_source> 
    | left_table_source { CROSS | OUTER } APPLY right_table_source 
    | [ ( ] <joined_table> [ ) ] 
}
<join_type> ::= 
    [ { INNER | { { LEFT | RIGHT | FULL } [ OUTER ] } } [ <join_hint> ] ]
    JOIN

<pivoted_table> ::=
        table_source PIVOT <pivot_clause> [ AS ] table_alias

<pivot_clause> ::=
        ( aggregate_function ( value_column [ [ , ]...n ]) 
        FOR pivot_column 
        IN ( <column_list> ) 
    ) 

<unpivoted_table> ::=
        table_source UNPIVOT <unpivot_clause> [ AS ] table_alias

<unpivot_clause> ::=
        ( value_column FOR pivot_column IN ( <column_list> ) ) 

<column_list> ::=
          column_name [ ,...n ]

Argumentos

  • <table_source>
    Especifica el origen de una tabla, una vista, una tabla variable o una tabla derivada, con o sin alias, para utilizarlo en la instrucción Transact-SQL. Se pueden utilizar hasta 256 orígenes de tabla en una instrucción, aunque el límite varía en función de la memoria disponible y de la complejidad del resto de las expresiones de la consulta. Las consultas individuales pueden no admitir un máximo de 256 orígenes de tabla.

    [!NOTA]

    El rendimiento de las consultas se puede ver afectado si se hace referencia a un número elevado de tablas en ellas. El tiempo de compilación y optimización también se puede ver afectado por factores adicionales. Dichos factores pueden ser la presencia de índices y vistas indizadas en cada <table_source> y el tamaño de <select_list> en la instrucción SELECT.

    El orden de los orígenes de tabla después de la palabra clave FROM no afecta al conjunto de resultados que se devuelve. SQL Server devuelve los errores cuando aparecen nombres duplicados en la cláusula FROM.

  • table_or_view_name
    Es el nombre de una tabla o una vista.

    Si la tabla o la vista existen en otra base de datos de la misma instancia de SQL Server, utilice un nombre completo con el formato base_de_datos.esquema.nombre_de_objeto.

    Si la tabla o vista existe fuera de la instancia de SQL Server, use un nombre en cuatro partes con el formato servidor_vinculado.catálogo.esquema.objeto. Para obtener más información, vea sp_addlinkedserver (Transact-SQL). El nombre de cuatro partes de la tabla o la vista creado con la función OPENDATASOURCE como la parte de servidor del nombre también se puede utilizar para especificar el origen de tabla remoto. Cuando se especifica OPENDATASOURCE, es posible que database_name y schema_name no se puedan aplicar a todos los orígenes de datos y dependan de las capacidades del proveedor OLE DB que tiene acceso al objeto remoto. Para obtener más información, vea Consultas distribuidas.

  • [AS] table_alias
    Es un alias para table_source que se puede utilizar por comodidad o para distinguir una tabla o una vista en una autocombinación o una subconsulta. El alias suele ser un nombre de tabla abreviado que se utiliza para hacer referencia a columnas específicas de las tablas en una combinación. Si el mismo nombre de columna existe en más de una tabla en una combinación, SQL Server requiere que el nombre de columna sea calificado mediante un nombre de tabla, un nombre de vista o un alias. No se puede utilizar el nombre de la tabla si se ha definido un alias.

    Si se utiliza una tabla derivada, una función de conjuntos de filas o con valores de tabla, o una cláusula de operador (como PIVOT o UNPIVOT), el parámetro table_alias requerido al final de la cláusula es el nombre de tabla asociado para todas las columnas devueltas, incluidas las columnas de agrupación.

  • WITH (<table_hint> )
    Especifica que el optimizador de consultas utiliza una estrategia de optimización o bloqueo con esta tabla y para esta instrucción. Para obtener más información, vea Sugerencias de tabla (Transact-SQL).

  • rowset_function
    Especifica una de las funciones de conjuntos de filas, como OPENROWSET, que devuelve un objeto que se puede utilizar en lugar de una referencia de tabla. Para obtener más información acerca de la lista de funciones de conjuntos de filas, vea Funciones de conjuntos de filas (Transact-SQL).

    El uso de las funciones OPENROWSET y OPENQUERY para especificar que un objeto remoto depende de las capacidades del proveedor OLE DB que tiene acceso al objeto. Para obtener más información, vea Consultas distribuidas.

  • bulk_column_alias
    Es un alias opcional para sustituir el nombre de una columna en el conjunto de resultados. Los alias de columna se permiten solo en las instrucciones SELECT que utilizan la función OPENROWSET con la opción BULK. Si utiliza bulk_column_alias, especifique un alias para cada columna de tabla en el mismo orden que las columnas del archivo.

    [!NOTA]

    Este alias invalida al atributo NAME de los elementos COLUMN de un archivo de formato XML si está presente.

  • user_defined_function
    Especifica una función con valores de tabla.

  • OPENXML <openxml_clause>
    Proporciona una vista de un conjunto de filas en un documento XML. Para obtener más información, vea OPENXML (Transact-SQL).

  • derived_table
    Es una subconsulta que recupera filas de la base de datos. derived_table se utiliza como entrada de la consulta externa.

    derived_table puede utilizar la característica de constructor de filas de Transact-SQL para especificar varias filas. Por ejemplo, SELECT * FROM (VALUES (1, 2), (3, 4), (5, 6), (7, 8), (9, 10) ) AS MyTable(a, b);. Para obtener más información, vea Constructor con valores de tabla (Transact-SQL).

  • column_alias
    Es un alias opcional para sustituir el nombre de una columna en el conjunto de resultados de la tabla derivada. Incluya un alias de columna para cada columna de la lista de selección y delimite la lista de alias de columna con paréntesis.

  • <tablesample_clause>
    Especifica que se devuelva un ejemplo de los datos de la tabla. El ejemplo puede ser aproximado. Esta cláusula se puede utilizar en cualquier tabla principal o combinada de una instrucción SELECT, UPDATE o DELETE. TABLESAMPLE no se puede especificar con vistas. Para obtener más información, vea Limitar los conjuntos de resultados con TABLESAMPLE.

    [!NOTA]

    Si utiliza TABLESAMPLE en bases de datos actualizadas a SQL Server, el nivel de compatibilidad de la base de datos se debe establecer en 90 o más alto. Para establecer el nivel de compatibilidad de la base de datos, vea Nivel de compatibilidad de ALTER DATABASE (Transact-SQL).

  • SYSTEM
    Se trata de un método de muestreo dependiente de la implementación especificado por los estándares ISO. En SQL Server, es el único método de muestreo disponible y se aplica de forma predeterminada. SYSTEM aplica un método de muestreo basado en páginas en el que se elige un conjunto de páginas aleatorio de la tabla para el ejemplo y todas las filas de dichas páginas se devuelven como el subconjunto de ejemplo. Para obtener más información, vea Limitar los conjuntos de resultados con TABLESAMPLE.

  • sample_number
    Es una expresión numérica constante exacta o aproximada que representa el porcentaje o el número de filas. Si se especifica con PERCENT, sample_number se convierte implícitamente a un valor float; en caso contrario, se convierte en bigint. PERCENT es el valor predeterminado.

  • PERCENT
    Especifica que se debe recuperar de la tabla el porcentaje sample_number de filas de la tabla. Si se especifica PERCENT, SQL Server devuelve un valor aproximado del porcentaje especificado. Si se especifica PERCENT, la expresión sample_number debe dar como resultado un valor comprendido entre 0 y 100.

  • ROWS
    Especifica que se recupere aproximadamente el número sample_number de filas. Si se especifica ROWS, SQL Server devuelve una aproximación del número de filas especificado. Si se especifica ROWS, la expresión sample_number debe ser un valor entero mayor que cero.

  • REPEATABLE
    Indica que el ejemplo seleccionado se puede devolver de nuevo. Si se especifica con el mismo valor de repeat_seed , SQL Server devuelve el mismo subconjunto de filas siempre que no se hayan realizado cambios en las filas de la tabla. Si se especifica con otro valor de repeat_seed, es probable que SQL Server devuelva un muestra distinto de filas de la tabla. Se consideran cambios en la tabla las siguientes acciones: insertar, actualizar, eliminar, volver a generar o desfragmentar índices, y restaurar o adjuntar bases de datos.

  • repeat_seed
    Es una expresión de tipo entero constante utilizada por SQL Server para generar un número aleatorio. repeat_seed es de tipo bigint. Si no se especifica repeat_seed, SQL Server asigna un valor de forma aleatoria. Para un valor repeat_seed específico, el resultado del muestreo es siempre el mismo si no ha aplicado ningún cambio a la tabla. La expresión repeat_seed debe ser un entero mayor que cero.

  • <joined_table>
    Es un conjunto de resultados producto de dos o más tablas. Para varias combinaciones, utilice paréntesis para cambiar el orden natural de las combinaciones.

  • <join_type>
    Especifica el tipo de operación de combinación.

  • INNER
    Especifica que se devuelvan todos los pares de filas coincidentes. Rechaza las filas no coincidentes de las dos tablas. Si no se especifica ningún tipo de combinación, éste es el valor predeterminado.

  • FULL [ OUTER ]
    Especifica que una fila de la tabla de la derecha o de la izquierda, que no cumpla la condición de combinación, se incluya en el conjunto de resultados y que las columnas que correspondan a la otra tabla se establezcan en NULL. De esta forma se agregan más filas a las que se suelen devolver con INNER JOIN.

  • LEFT [ OUTER ]
    Especifica que todas las filas de la tabla izquierda que no cumplan la condición de combinación se incluyan en el conjunto de resultados, con las columnas de resultados de la otra tabla establecidas en NULL, además de todas las filas devueltas por la combinación interna.

  • RIGHT [OUTER]
    Especifica que todas las filas de la tabla derecha que no cumplan la condición de combinación se incluyan en el conjunto de resultados, con las columnas de resultados de la otra tabla establecidas en NULL, además de todas las filas devueltas por la combinación interna.

  • <join_hint>
    Especifica que el optimizador de consultas de SQL Server debe utilizar una sugerencia de combinación o un algoritmo de ejecución por cada combinación especificada en la cláusula FROM de la consulta. Para obtener más información, vea Sugerencias de combinación (Transact-SQL).

  • JOIN
    Indica que se va a ejecutar la operación de combinación especificada entre los orígenes de tabla o vistas indicados.

  • ON <search_condition>
    Especifica la condición en la que se basa la combinación. La condición puede especificar cualquier predicado, aunque se suelen utilizar columnas y operadores de comparación; por ejemplo:

    SELECT p.ProductID, v.VendorID
    FROM Production.Product AS p 
    JOIN Purchasing.ProductVendor AS v
    ON (p.ProductID = v.ProductID);
    

    Cuando la condición especifique columnas, no será necesario que tengan el mismo nombre o el mismo tipo de datos; sin embargo, si los tipos de datos no son idénticos, deben ser compatibles o tratarse de tipos que SQL Server pueda convertir implícitamente. Si los tipos de datos no se pueden convertir implícitamente, la condición debe convertir de forma explícita el tipo de datos mediante la función CONVERT.

    Puede haber predicados relacionados solamente con una de las tablas combinadas de la cláusula ON. Estos predicados también pueden estar en la cláusula WHERE de la consulta. Aunque la posición de estos predicados no produce ninguna diferencia en el caso de combinaciones INNER, podría generar un resultado diferente si estuvieran implicadas las combinaciones OUTER. La razón es que los predicados de la cláusula ON se aplican a la tabla antes de la combinación, mientras la cláusula WHERE se aplica de forma semántica al resultado de la combinación.

    Para obtener más información acerca de los predicados y las condiciones de búsqueda, vea Condiciones de búsqueda (Transact-SQL).

  • CROSS JOIN
    Especifica el producto cruzado resultante de dos tablas. Devuelve las mismas filas que se devolverían si no se especificara la cláusula WHERE en una combinación de estilo antiguo distinta del estilo de SQL-92.

  • left_table_source{ CROSS | OUTER } APPLY right_table_source
    Especifica que el argumento right_table_source del operador APPLY se evalúe con respecto a cada fila de left_table_source. Esta funcionalidad es útil si right_table_source contiene una función con valores de tabla que toma los valores de columna de left_table_source como uno de sus argumentos.

    Se debe especificar OUTER o CROSS con APPLY. Si se especifica CROSS, no se genera ninguna fila cuando right_table_source se evalúa con respecto a una fila especificada de left_table_source y se devuelve un conjunto de resultados vacío.

    Si se especifica OUTER, se genera una fila para cada fila de left_table_source, incluso si right_table_source se evalúa con respecto a dicha fila y devuelve un conjunto de resultados vacío.

    Para obtener más información, vea la sección Notas y Usar APPLY.

  • left_table_source
    Es un origen de tabla según se ha definido en el argumento anterior. Para obtener más información, vea la sección Notas.

  • right_table_source
    Es un origen de tabla según se ha definido en el argumento anterior. Para obtener más información, vea la sección Notas.

  • table_source PIVOT <pivot_clause>
    Especifica que table_source se dinamice en función de pivot_column. table_source es una tabla o una expresión de tabla. La salida es una tabla que contiene todas las columnas de table_source, excepto pivot_column y value_column. Las columnas de table_source, excepto pivot_column y value_column, se denominan columnas de agrupamiento del operador dinámico.

    PIVOT realiza una operación de agrupamiento en la tabla de entrada con respecto a las columnas de agrupamiento y devuelve una fila para cada grupo. Además, el resultado contiene una columna para cada valor especificado en column_list que aparece en el parámetro pivot_column de input_table.

    Para obtener más información, vea la sección Notas y Usar PIVOT y UNPIVOT.

    [!NOTA]

    Si utiliza PIVOT en bases de datos actualizadas a SQL Server, el nivel de compatibilidad de la base de datos se debe establecer en 90 o más alto. Para obtener más información acerca de la configuración del nivel de compatibilidad de la base de datos, vea Nivel de compatibilidad de ALTER DATABASE (Transact-SQL).

  • aggregate_function
    Es una función de agregado del sistema o definida por el usuario que acepta una o más entradas. La función de agregado no puede variar con respecto a los valores NULL. Una función de agregado invariable con respecto a los valores NULL no tiene en cuenta los valores NULL del grupo mientras evalúa el valor del agregado.

    No se permite la función de agregado del sistema COUNT(*).

  • value_column
    Es la columna de valores del operador PIVOT. Si se utiliza con UNPIVOT, value_column no puede ser el nombre de una columna existente en el parámetro table_source de entrada.

  • FOR pivot_column
    Es la columna dinámica del operador PIVOT. pivot_column debe ser de un tipo convertible de forma implícita o explícita a nvarchar(). Esta columna no puede ser image o rowversion.

    Si se utiliza UNPIVOT, pivot_column es el nombre de la columna de salida restringida a partir de table_source. No puede haber ninguna columna en table_source con ese nombre.

  • IN ( column_list )
    En la cláusula PIVOT, se incluyen los valores de pivot_column que se van a convertir en los nombres de columnas de la tabla de salida. La lista no puede especificar ningún nombre de columna que ya exista en el parámetro table_source de entrada que se está dinamizando.

    En la cláusula UNPIVOT, se incluyen las columnas de table_source que se va a restringir en una sola pivot_column.

  • table_alias
    Es el nombre de alias de la tabla de salida. Se debe especificar pivot_table_alias.

  • UNPIVOT < unpivot_clause >
    Especifica que la tabla de entrada se restringe a partir de varias columnas de column_list en una sola columna denominada pivot_column.

    Para obtener más información, vea la sección Notas y Usar PIVOT y UNPIVOT.

    [!NOTA]

    Si utiliza UNPIVOT en bases de datos actualizadas a SQL Server, el nivel de compatibilidad de la base de datos se debe establecer en 90 o más alto. Para establecer el nivel de compatibilidad de la base de datos, vea Nivel de compatibilidad de ALTER DATABASE (Transact-SQL).

Notas

La cláusula FROM admite la sintaxis SQL-92-SQL para las tablas combinadas y las tablas derivadas. La sintaxis SQL-92 proporciona los operadores de combinación INNER, LEFT OUTER, RIGHT OUTER, FULL OUTER y CROSS.

En las vistas, tablas derivadas y subconsultas se admiten las operaciones UNION y JOIN dentro de una cláusula FROM.

Una autocombinación es una tabla que se combina consigo misma. Las inserciones o actualizaciones basadas en una autocombinación siguen el orden de la cláusula FROM.

Las versiones anteriores de SQL Server admiten la definición de combinaciones externas que utilizan los operadores *= y =* en la cláusula WHERE. SQL Server versión 7.0 admite el estándar ISO. De esta manera, los operadores de combinación se proporcionan en la cláusula FROM. Cuando el nivel de compatibilidad de la base de datos se establece en 90 o un valor superior, los operadores de combinación externa (*= y =*) no se admiten.

Puesto que SQL Server considera las estadísticas de cardinalidad y distribución de servidores vinculados que proporcionan estadísticas de distribución de columnas, no es necesaria la sugerencia de combinación REMOTE para exigir la evaluación de una combinación de forma remota. El procesador de consultas de SQL Server considera las estadísticas remotas y determina si es apropiada una estrategia de combinación remota. La sugerencia de combinación REMOTE es útil para los proveedores que no proporcionan estadísticas de distribución de columnas. Para obtener más información, vea Requisitos de las estadísticas de distribución para proveedores OLE DB.

Para obtener más información acerca de cómo trabajar con combinaciones, vea Aspectos básicos de las combinaciones y Usar combinaciones.

Usar APPLY

Los operandos izquierdo y derecho del operador APPLY son expresiones de tabla. La diferencia principal entre estos operandos es que right_table_source puede utilizar una función con valores de tabla que tome una columna de left_table_source como uno de los argumentos de la función. left_table_source puede incluir funciones con valores de tabla, pero no puede contener argumentos que sean columnas de right_table_source.

El operador APPLY funciona del siguiente modo para generar el origen de tabla para la cláusula FROM:

  1. Evalúa right_table_source con respecto a cada fila de left_table_source para generar conjuntos de filas.

    Los valores de right_table_source dependen de left_table_source. right_table_source se puede representar aproximadamente de este modo: TVF(left_table_source.row), donde TVF es una función con valores de tabla.

  2. Combina los conjuntos de resultados generados para cada fila en la evaluación de right_table_source con left_table_source, mediante una operación UNION ALL.

    La lista de columnas que genera el resultado del operador APPLY es el conjunto de columnas de left_table_source combinado con la lista de columnas de right_table_source.

Usar PIVOT y UNPIVOT

pivot_column y value_column son columnas de agrupamiento utilizadas por el operador PIVOT. Para obtener el conjunto de resultados de salida, PIVOT aplica el siguiente proceso:

  1. Realiza una operación GROUP BY en input_table para las columnas de agrupamiento y genera una fila de resultados para cada grupo.

    Las columnas de agrupamiento de la fila de salida obtienen los valores de columna correspondientes para dicho grupo en input_table.

  2. Genera valores para las columnas de la lista de columnas para cada fila de resultados mediante las siguientes operaciones:

    1. Agrupación adicional de las filas generadas en GROUP BY en el paso anterior para pivot_column.

      Para cada columna de salida de column_list, se selecciona un subgrupo que cumple la condición:

      pivot_column = CONVERT(<data type of pivot_column>, 'output_column')

    2. aggregate_function se evalúa con respecto a value_column en este subgrupo y su resultado se devuelve como un valor de output_column correspondiente. Si el subgrupo está vacío, SQL Server genera un valor NULL para output_column. Si la función de agregado es COUNT y el subgrupo está vacío, se devuelve cero (0).

Para obtener más información, vea Usar PIVOT y UNPIVOT.

Permisos

Requiere los permisos para la instrucción DELETE, SELECT o UPDATE.

Ejemplos

A. Usar una cláusula FROM sencilla

En el siguiente ejemplo se recuperan las columnas TerritoryID y Name de la tabla SalesTerritory de la base de datos de ejemplo AdventureWorks.

USE AdventureWorks ;
GO
SELECT TerritoryID, Name
FROM Sales.SalesTerritory
ORDER BY TerritoryID ;

Éste es el conjunto de resultados.

TerritoryID Name                          
----------- ------------------------------
1           Northwest                     
2           Northeast                     
3           Central                       
4           Southwest                     
5           Southeast                     
6           Canada                        
7           France                        
8           Germany                       
9           Australia                     
10          United Kingdom                
(10 row(s) affected)

B. Usar las sugerencias del optimizador TABLOCK y HOLDLOCK

En la siguiente transacción parcial se muestra cómo colocar un bloqueo explícito de tabla compartida en Employee y cómo leer el índice. El bloqueo se mantiene durante toda la transacción.

USE AdventureWorks ;
GO
BEGIN TRAN
SELECT COUNT(*) 
FROM HumanResources.Employee WITH (TABLOCK, HOLDLOCK) ;

C. Usar la sintaxis CROSS JOIN de SQL-92

Este ejemplo devuelve el producto resultante de las tablas Employee y Department. Se devuelve la lista de todas las combinaciones posibles de las filas de EmployeeID y todas las filas con el nombre Department .

USE AdventureWorks ;
GO
SELECT e.EmployeeID, d.Name AS Department
FROM HumanResources.Employee AS e
CROSS JOIN HumanResources.Department AS d
ORDER BY e.EmployeeID, d.Name ;

D. Usar la sintaxis FULL OUTER JOIN de SQL-92

En el siguiente ejemplo se devuelve el nombre del producto y los pedidos de venta correspondientes de la tabla SalesOrderDetail. Además, se devuelven todos los pedidos de venta que no incluyen ningún producto en la tabla Product y todos los productos con un pedido de venta distinto del especificado en la tabla Product.

USE AdventureWorks ;
GO
-- The OUTER keyword following the FULL keyword is optional.
SELECT p.Name, sod.SalesOrderID
FROM Production.Product AS p
FULL OUTER JOIN Sales.SalesOrderDetail AS sod
ON p.ProductID = sod.ProductID
WHERE p.ProductID IS NULL OR sod.ProductID IS NULL
ORDER BY p.Name ;

E. Usar la sintaxis LEFT OUTER JOIN de SQL-92

Este ejemplo combina dos tablas en ProductID y mantiene las filas no coincidentes de la tabla izquierda. La tabla Product coincide con la tabla SalesOrderDetail en las columnas ProductID de cada tabla. Todos los productos, ordenados y no ordenados, aparecen en el conjunto de resultados.

USE AdventureWorks ;
GO
SELECT p.Name, sod.SalesOrderID
FROM Production.Product AS p
LEFT OUTER JOIN Sales.SalesOrderDetail AS sod
ON p.ProductID = sod.ProductID
ORDER BY p.Name ;

F. Usar la sintaxis INNER JOIN de SQL-92

En el siguiente ejemplo se devuelven todos los nombres de productos e identificadores de pedidos de venta.

USE AdventureWorks ;
GO
-- By default, SQL Server performs an INNER JOIN if only the JOIN 
-- keyword is specified.
SELECT p.Name, sod.SalesOrderID
FROM Production.Product AS p
INNER JOIN Sales.SalesOrderDetail AS sod
ON p.ProductID = sod.ProductID
ORDER BY p.Name ;

G. Usar la sintaxis RIGHT OUTER JOIN de SQL-92

Este ejemplo combina dos tablas en TerritoryID y mantiene las filas no coincidentes de la tabla derecha. La tabla SalesTerritory coincide con la tabla SalesPerson en la columna TerritoryID de cada tabla. Todos los vendedores aparecen en el conjunto de resultados con independencia de que tengan un territorio asignado.

USE AdventureWorks ;
GO
SELECT st.Name AS Territory, sp.SalesPersonID
FROM Sales.SalesTerritory AS st 
RIGHT OUTER JOIN Sales.SalesPerson AS sp
ON st.TerritoryID = sp.TerritoryID ;

H. Usar las sugerencias de combinación HASH y MERGE

En el siguiente ejemplo se realiza una combinación de tres tablas entre las tablas Product, ProductVendor y Vendor para generar una lista de productos y sus proveedores. El optimizador de consultas combina Product y ProductVendor (p y pv) mediante una combinación MERGE. A continuación, los resultados de la combinación MERGE de Product y ProductVendor (p y pv) se combinan mediante HASH con la tabla Vendor para generar (p y pv) y v.

Nota importanteImportante

Después de especificar una sugerencia de combinación, la palabra clave INNER ya no es opcional y se tiene que incluir explícitamente para hacer combinaciones INNER JOIN.

USE AdventureWorks ;
GO
SELECT p.Name AS ProductName, v.Name AS VendorName
FROM Production.Product AS p 
INNER MERGE JOIN Purchasing.ProductVendor AS pv 
ON p.ProductID = pv.ProductID
INNER HASH JOIN Purchasing.Vendor AS v
ON pv.VendorID = v.VendorID
ORDER BY p.Name, v.Name ;

I. Usar una tabla derivada

En el siguiente ejemplo se utiliza una tabla derivada y una instrucción SELECT después de la cláusula FROM para devolver los nombres y apellidos de todos los empleados y las ciudades en que residen.

USE AdventureWorks ;
GO
SELECT RTRIM(c.FirstName) + ' ' + LTRIM(c.LastName) AS Name,
 d.City
FROM Person.Contact AS c
INNER JOIN HumanResources.Employee e ON c.ContactID = e.ContactID 
INNER JOIN
   (SELECT ea.AddressID, ea.EmployeeID, a.City 
    FROM Person.Address AS a
    INNER JOIN HumanResources.EmployeeAddress AS ea
    ON a.AddressID = ea.AddressID) AS d
ON e.EmployeeID = d.EmployeeID
ORDER BY c.LastName, c.FirstName;

J. Usar TABLESAMPLE para leer datos de un ejemplo de filas de una tabla

En el siguiente ejemplo se utiliza TABLESAMPLE en la cláusula FROM para devolver aproximadamente un 10 por ciento de todas las filas de la tabla Customer de la base de datos AdventureWorks.

USE AdventureWorks ;
GO
SELECT *
FROM Sales.Customer TABLESAMPLE SYSTEM (10 PERCENT) ;

K. Usar APPLY

En el siguiente ejemplo se da por supuesto que las siguientes tablas con el esquema que se indica existen en la base de datos:

  • Departments: DeptID, DivisionID, DeptName, DeptMgrID

  • EmpMgr: MgrID, EmpID

  • Employees: EmpID, EmpLastName, EmpFirstName, EmpSalary

Se incluye además una función con valores de tabla, GetReports(MgrID), que devuelve la lista de todos los empleados (EmpID, EmpLastName, EmpSalary) que dependen directa o indirectamente del MgrID especificado.

En el ejemplo se utiliza APPLY para devolver todos los departamentos y todos los empleados de cada departamento. Si un departamento concreto no tiene ningún empleado, no se devuelve ninguna fila para dicho departamento.

SELECT DeptID, DeptName, DeptMgrID, EmpID, EmpLastName, EmpSalary
FROM Departments d CROSS APPLY dbo.GetReports(d.DeptMgrID) ;

Si desea que la consulta genere filas para los departamentos sin empleados, lo que genera valores NULL para las columnas EmpID, EmpLastName y EmpSalary, utilice OUTER APPLY.

SELECT DeptID, DeptName, DeptMgrID, EmpID, EmpLastName, EmpSalary
FROM Departments d OUTER APPLY dbo.GetReports(d.DeptMgrID) ;

L. Usar PIVOT y UNPIVOT

En el siguiente ejemplo se devuelve el número de pedidos de compra realizados por los empleados con los identificadores 164, 198, 223, 231 y 233, clasificados en categorías por identificador de proveedor.

USE AdventureWorks;
GO
SELECT VendorID, [164] AS Emp1, [198] AS Emp2, [223] AS Emp3, [231] AS Emp4, [233] AS Emp5
FROM 
(SELECT PurchaseOrderID, EmployeeID, VendorID
FROM Purchasing.PurchaseOrderHeader) AS p
PIVOT
(
COUNT (PurchaseOrderID)
FOR EmployeeID IN
( [164], [198], [223], [231], [233] )
) AS pvt
ORDER BY VendorID;

A continuación se muestra un conjunto de resultados parcial:

VendorID    Emp1        Emp2        Emp3        Emp4        Emp5

----------------------------------------------------------------

1           4           3           5           4           4

2           4           1           5           5           5

3           4           3           5           4           4

4           4           2           5           5           4

5           5           1           5           5           5

Para anular la dinamización de la tabla, debe dar por supuesto que el conjunto de resultados generado en el ejemplo anterior se almacena como pvt. La consulta sería la siguiente.

--Create the table and insert values as portrayed in the previous example.
CREATE TABLE dbo.pvt (VendorID int, Emp1 int, Emp2 int,
Emp3 int, Emp4 int, Emp5 int);
GO
-- Insert 5 rows into the table.
INSERT INTO dbo.pvt VALUES (1,4,3,5,4,4),(2,4,1,5,5,5),(3,4,3,5,4,4),
                           (4,4,2,5,5,4),(5,5,1,5,5,5);
GO
--Unpivot the table.
SELECT VendorID, Employee, Orders
FROM 
    (SELECT VendorID, Emp1, Emp2, Emp3, Emp4, Emp5
    FROM dbo.pvt) AS p
UNPIVOT
    (Orders FOR Employee IN 
        (Emp1, Emp2, Emp3, Emp4, Emp5)
)AS unpvt;
GO

A continuación se muestra un conjunto de resultados parcial:

VendorID    Employee    Orders

------------------------------

1           Emp1        4

1           Emp2        3

1           Emp3        5

1           Emp4        4

1           Emp5        4

2           Emp1        4

2           Emp2        1

2           Emp3        5

2           Emp4        5

2           Emp5        5