Uso del operador APPLY
Como alternativa a combinar o comparar filas de dos conjuntos, SQL Server proporciona un mecanismo para aplicar una expresión de tabla de un conjunto en cada fila del otro conjunto. El operador APPLY habilita las consultas que evalúan las filas de un conjunto de entrada en la expresión que define el segundo conjunto de entrada. APPLY es realmente un operador de tabla, no un operador set y forma parte de la cláusula FROM. APPLY es más parecido a una unión, en lugar de un operador de conjunto que actúa sobre dos conjuntos de resultados compatibles de consultas.
Conceptualmente, el operador APPLY es similar a una subconsulta correlacionada en que aplica una expresión de tabla correlacionada a cada fila de una tabla. Sin embargo, APPLY devuelve un resultado con valores de tabla en lugar de un resultado escalar o multivalor. Por ejemplo, la expresión de tabla podría ser una función con valores de tabla. Puede pasar elementos de la fila izquierda como parámetros de entrada a la función con valores de tabla.
Hay dos formas de APPLY:
- CROSS APPLY
- OUTER APPLY
La sintaxis de APPLY es la siguiente:
SELECT <column_list>
FROM left_table_source { CROSS | OUTER } APPLY right_table_source
Esto se explica mejor con un ejemplo. En el primer ejemplo se usa inner JOIN para devolver columnas de las tablas siguientes:
- SalesLT.SalesOrderHeader.
- SalesLT.SalesOrderDetail.
En el ejemplo de código siguiente, las tablas se combinan mediante INNER JOIN:
SELECT oh.SalesOrderID, oh.OrderDate,od.ProductID, od.UnitPrice, od.Orderqty
FROM SalesLT.SalesOrderHeader AS oh
INNER JOIN SalesLT.SalesOrderDetail AS od
ON oh.SalesOrderID = od.SalesOrderID;
En el ejemplo de código siguiente, CROSS APPLY aplica el origen de la tabla derecha a cada fila del origen de la tabla izquierda. Solo se devuelven filas con resultados en la tabla izquierda y en la tabla derecha. La mayoría de las instrucciones INNER JOIN se pueden volver a escribir como instrucciones CROSS APPLY.
SELECT oh.SalesOrderID, oh.OrderDate,
od.ProductID, od.UnitPrice, od.Orderqty
FROM SalesLT.SalesOrderHeader AS oh
CROSS APPLY (SELECT productid, unitprice, Orderqty
FROM SalesLT.SalesOrderDetail AS od
WHERE oh.SalesOrderID = SalesOrderID
) AS od;
En ambos casos, el conjunto de resultados es el mismo: