   04:28

# CROSS APPLY / OUTER APPLY page 2

Let's imagine that along with maximal price, you need minimal price, average price and so on. Correlated subquery in SELECT clause must return only single value, so we are forced to duplicate sql-code for each aggregate:  Console
`SELECT *, (SELECT MAX(price) FROM Laptop L2JOIN  Product P1 ON L2.model=P1.model WHERE maker = (SELECT maker FROM Product P2 WHERE P2.model= L1.model)) max_price,(SELECT MIN(price) FROM Laptop L2JOIN  Product P1 ON L2.model=P1.model WHERE maker = (SELECT maker FROM Product P2 WHERE P2.model= L1.model)) min_priceFROM Laptop L1;`
etc.

But when using CROSS APPLY, we simply add into subquery a wanted aggregate function as a new column:  Console
`SELECT * FROM laptop L1 CROSS APPLY (SELECT MAX(price) max_price, MIN(price) min_price  FROM Laptop L2JOIN  Product P1 ON L2.model=P1.model WHERE maker = (SELECT maker FROM Product P2 WHERE P2.model= L1.model)) X;`

Another example.

Combine each row in the Laptop table with next row in the order of sorting by (model, code).

The code column is used in sorting to get single-valued ordering for rows with the same value in the model column. We'll use CROSS APPLY operator to pass into subquery the parameters of a current row and take the first row under this current row in the given sorting. So,  Console
`SELECT * FROM laptop L1CROSS APPLY(SELECT TOP 1 * FROM Laptop L2 WHERE L1.model < L2.model OR (L1.model = L2.model AND L1.code < L2.code) ORDER BY model, code) XORDER BY L1.model;`

Try to solve this problem using standard means and compare the efforts required.

#### OUTER APPLY operator

As the results of above query have shown, we "lost" the last (sixth) row in Laptop table because there is no row to
combine it with. In other words, CROSS APPLY behaves itself as inner join. An analog of outer (left) join is just OUTER APPLY operator. The latter differs from CROSS APPLY in just that OUTER APPLY returns all the rows from left-hand table when replacing the missing values from right-hand table by NULLs.

Replacement CROSS APPLY by OUTER APPLY illustrates above said.  Console
`SELECT * FROM laptop L1OUTER APPLY(SELECT TOP 1 * FROM Laptop L2 WHERE L1.model < L2.model OR (L1.model = L2.model AND L1.code < L2.code) ORDER BY model, code) XORDER BY L1.model;`

Another popular problem is to output the same number of rows for each group, for example when it is needed to advertise the 5 most popular goods within each category. Let's consider the following exercise.

From Product table, retrieve for each group characterized by the type of the product three models with the lowest numbers.

Solutions to this problem on the site sql-ex.ru we'll supplement with another one solution using CROSS APPLY.
The idea of the solution consists in joining of unique product types (the first query) with the query which returns three models of the each type from the first query in accordance with given sorting.  Console
`SELECT X.* FROM (SELECT DISTINCT type FROM product) Pr1 CROSS APPLY (SELECT TOP 3 * FROM product Pr2 WHERE  Pr1.type=Pr2.type ORDER BY pr2.model) x;`

 Pages 1 2 3