programming4us
programming4us
DATABASE

SQL Server 2008 : Transact-SQL Programming - The APPLY Operator

- How To Install Windows Server 2012 On VirtualBox
- How To Bypass Torrent Connection Blocking By Your ISP
- How To Install Actual Facebook App On Kindle Fire
6/7/2011 11:51:45 AM
The APPLY relational operator allows you to invoke a table-valued function once per each row of an outer table expression. You specify APPLY in the FROM clause of a query, similarly to the way you use the JOIN operator. APPLY can take two forms: CROSS APPLY and OUTER APPLY.

CROSS APPLY

CROSS APPLY invokes a table-valued function for each row in an outer table expression, returning a unified result set out of all the results returned by the individual invocations of the table-valued function. The columns in the outer table are used as arguments to the table-valued function. If the table-valued function returns an empty set for a given outer row, that outer row is not returned in the result.

For example, the table-valued function in Listing 1 accepts stor_id and an integer as arguments and returns a list of the top N largest orders for that store. The number of rows returned is determined by the value passed to the second parameter. If you call this function with stor_id and a number of rows, it returns that many rows, ordered by the qty of the order, in descending order.

Listing 1. A Table-Valued Function That Returns the Top N Orders for stor_id
CREATE FUNCTION dbo.fn_GetTopOrders(@stor_id AS char(4), @n AS INT)
RETURNS TABLE
AS
RETURN
SELECT TOP(@n) *
FROM dbo.sales
WHERE stor_id = @stor_id
ORDER BY qty DESC
GO

Following is a sample invocation of the function in Listing 43.57:

select * from dbo.fn_GetTopOrders ('B251', 3)
go

stor_id ord_num ord_date qty payterms title_id
------- ------------------ ----------------------- ---- ------------ --------
B251 ONQQQQQQQQQQQQQQQ 2008-01-23 00:00:00.000 1740 Net 60 CH6808
B251 ONKKKKKKKKKKKKKKKK 2007-11-04 00:00:00.000 1704 Net 60 FI9420
B251 ONTTTTTTTTTTTTTTTT 2008-02-22 00:00:00.000 1560 Net 60 FI8000



If you want to generate a result set that shows each store name and the top three largest orders for each store, you can use the CROSS APPLY function to join to the dbo.fn_GetTopOrders function for each stor_id in the outer query, as shown in Listing 2.

Listing 2. Using CROSS APPLY
select st.stor_id, stor_name, s.ord_date, s.qty
from stores st
cross apply
dbo.fn_GetTopOrders (st.stor_id, 3) as s
where st.state = 'MI'
and st.stor_name in ('Barnes & Noble', 'B Dalton BookSeller', 'Waldenbooks')
order by stor_id, s.qty DESC
go

stor_id stor_name ord_date qty
------- ------------------- ----------------------- ------
B251 B Dalton Bookseller 2008-01-23 00:00:00.000 1740
B251 B Dalton Bookseller 2007-11-04 00:00:00.000 1704
B251 B Dalton Bookseller 2008-02-22 00:00:00.000 1560
B510 Barnes & Noble 2008-08-13 00:00:00.000 1464
B510 Barnes & Noble 2007-10-08 00:00:00.000 1200
B510 Barnes & Noble 2006-01-08 00:00:00.000 924
P963 Waldenbooks 2008-07-07 00:00:00.000 1668
P963 Waldenbooks 2006-12-30 00:00:00.000 1068
P963 Waldenbooks 2006-03-29 00:00:00.000 1032
Q017 Waldenbooks 2007-11-02 00:00:00.000 1776
Q017 Waldenbooks 2006-06-15 00:00:00.000 1704
Q017 Waldenbooks 2007-02-24 00:00:00.000 1548



CROSS APPLY returns only rows from the outer table that produce a result set from the table-valued function. If a store has no orders, it does not appear in the result set. To include all rows from the outer table, use OUTER APPLY.

OUTER APPLY

OUTER APPLY returns from the outer table both rows that produce a result set and rows that do not. Rows that do not produce a result set from the table-valued function return NULL values in the columns produced by the table-valued function.

The following example is similar to the query in Listing 43.58 but replaces CROSS APPLY with the OUTER APPLY clause:

select st.stor_id, stor_name, s.ord_date, s.qty
from stores st
outer apply
dbo.fn_GetTopOrders (st.stor_id, 3) as s
where st.state = 'MI'
and st.stor_name in ('Barnes & Noble', 'B Dalton BookSeller', 'Waldenbooks')
order by stor_id, s.qty DESC
go

stor_id stor_name ord_date qty
------- ------------------- ----------------------- ------
B251 B Dalton Bookseller 2008-01-23 00:00:00.000 1740
B251 B Dalton Bookseller 2007-11-04 00:00:00.000 1704
B251 B Dalton Bookseller 2008-02-22 00:00:00.000 1560
B510 Barnes & Noble 2008-08-13 00:00:00.000 1464
B510 Barnes & Noble 2007-10-08 00:00:00.000 1200
B510 Barnes & Noble 2006-01-08 00:00:00.000 924
B511 Barnes & Noble NULL NULL
P963 Waldenbooks 2008-07-07 00:00:00.000 1668
P963 Waldenbooks 2006-12-30 00:00:00.000 1068
P963 Waldenbooks 2006-03-29 00:00:00.000 1032
Q017 Waldenbooks 2007-11-02 00:00:00.000 1776
Q017 Waldenbooks 2006-06-15 00:00:00.000 1704
Q017 Waldenbooks 2007-02-24 00:00:00.000 1548
Other  
  •  SQL Server 2008 : Transact-SQL Programming - PIVOT and UNPIVOT
  •  SQL Server 2008 : Transact-SQL Programming - Ranking Functions
  •  SQL Server 2008 : Transact-SQL Programming - Common Table Expressions
  •  SQL Server 2008 : Transact-SQL Programming - The OUTPUT Clause
  •  SQL Server 2008 : Transact-SQL Programming - TOP Enhancements
  •  SQL Server 2008 : Transact-SQL Programming - The max Specifier
  •  SQL Server 2008 : T-SQL Tips and Tricks (part 3) - Generating T-SQL Statements with T-SQL & De-Duping Data with Ranking Functions
  •  SQL Server 2008 : T-SQL Tips and Tricks (part 2) - Using CONTEXT_INFO & Working with Outer Joins
  •  SQL Server 2008 : T-SQL Tips and Tricks (part 1) - Date Calculations & Sorting Results with the GROUPING Function
  •  SQL Server 2008 : General T-SQL Performance Recommendations
  •  
    programming4us
     
     
    programming4us