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
Execute
SELECT *, (SELECTMAX(price)FROM Laptop L2
JOIN Product P1 ON L2.model=P1.model
WHERE maker = (SELECT maker FROM Product P2 WHERE P2.model= L1.model)) max_price,
(SELECTMIN(price)FROM Laptop L2
JOIN Product P1 ON L2.model=P1.model
WHERE maker = (SELECT maker FROM Product P2 WHERE P2.model= L1.model)) min_price
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
Execute
SELECT * FROM laptop L1
CROSSAPPLY
(SELECTTOP1 * FROM Laptop L2
WHERE L1.model < L2.model OR(L1.model = L2.model AND L1.code < L2.code)
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
Execute
SELECT * FROM laptop L1
OUTERAPPLY
(SELECTTOP1 *
FROM Laptop L2
WHERE L1.model < L2.model OR(L1.model = L2.model AND L1.code < L2.code)
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
Execute
SELECT X.* FROM
(SELECTDISTINCT type FROM product) Pr1
CROSSAPPLY
(SELECTTOP3 * FROM product Pr2 WHERE Pr1.type=Pr2.type ORDERBY pr2.model) x;