Add APPLY to Your TSQL Tool Belt

Every once in a while I stumble across some SQL keyword that I didn’t really know about, but is extremely useful.

The other day I came across APPLY, or rather CROSS APPLY.

After reading through documentation on how it works and articles about it, I had a bit of trouble understanding it because I couldn’t really find a simple explanation.

I am going to try to explain it as simply as possible so you can start using it right away.

How CROSS APPLY works

The basic idea behind CROSS APPLY is to allow you to join two sets of data together.

If you understand how INNER JOIN works, you already understand CROSS APPLY.

The only difference is CROSS APPLY also allows you to join in a set of data in which that set of data is created or dependent on each row in the first set.

So basically what that means is that for a normal join you would, for example, join two tables that shared a common key.

I could join my customer table to my orders table to see all the orders for a particular customer like so:

SELECT *
FROM
 orders o
 JOIN customers c
 	ON o.customerid = c.customerid
WHERE
 c.companyname = 'Around the Horn'

Notice how the join is operating on a key that exists independently in each table.

We could rewrite this to be exactly the same using the CROSS APPLY syntax instead like so:

SELECT *
FROM
  orders o
  CROSS APPLY (
    SELECT *  FROM
	   customers c
    WHERE
	   o.customerid = c.customerid) AS c
WHERE
  c.companyname = 'Around the Horn'

We can prove these results sets are exactly the same by using EXCEPT to make sure there are no rows in one set that aren’t in the other and then flipping it, like so:

SELECT *
FROM
    orders o
    CROSS APPLY (SELECT *
                 FROM
                     customers c
                 WHERE
                     o.customerid = c.customerid) AS c
WHERE
    c.companyname = 'Around the Horn'

EXCEPT
SELECT *
FROM
    orders o
    JOIN customers c
        ON o.customerid = c.customerid
WHERE
    c.companyname = 'Around the Horn'

Just run this exact query again swapping the SQL above the EXCEPT with the SQL below and make sure it has no results as well. If both of those queries have no results, then you know the results from each query are the same since EXCEPT will show any results that are in the top query but not in the bottom one.

So when is CROSS APPLY useful?

Remember how I said it can do more than a simple join? Joins are restricted to only joining two sets of data that could be queries independently of each other.

What if I said give me the three most recent orders for each customer?

Take a minute and think about how you would write that query. Go ahead and try to do it. I’ll wait.

There are a few ways to do it without using CROSS APPLY, but none of them are really very easy or perform very well.

Using CROSS APPLY it is simple though:

SELECT *
FROM
    customers c
    CROSS APPLY (
                 SELECT TOP 3 o.orderdate
                            , o.shipcity
                 FROM
                     orders o
                 WHERE
                     o.customerid = c.customerId
order by o.orderdate desc
) as top3;

So CROSS APPLY is useful whenever you have some data that you would want to be able to join against, but are forced to do some kind of sub-query instead because the data you are trying to join is not going to map well against a single key.

The other instance in which CROSS APPLY will be useful is when you are doing a sub-select that has more than one value you would like to use in your final query.

For example if you were sub-selecting from an Order Details table to match up order ids that had a Quantity greater than 5, that sub-select would need to return exactly one column in order for you to use it in your where clause. If you wanted to use other columns from the sub-select, you would have to do another sub-select for each of these columns.

If you first try to rewrite the sub-select as a JOIN and find that you can’t, you may be able to write it as a CROSS APPLY.

How to know when to use CROSS APPLY

There isn’t a good solid rule you can use to identify when you should use a CROSS APPLY but having the knowledge of CROSS APPLY and how it works can help you when you are trying to tune queries and you are having a difficult time constructing one. It is another option you can try.

Here are some general guidelines of times when you might want to use CROSS APPLY:

  • A query where the result set you want to JOIN against is in some way related to the data in the first set. (Example: one column in the first table tells you how many rows in the 2nd table to get)
  • A query where you are doing a sub-query, but need more than one value from the sub-query
  • Anywhere you are using a Common Table Expression (CTE) could possibly be rewritten as a CROSS APPLY
  • A query that has a large set of data it is joining against and then filtering out. You can change it to a CROSS APPLY that does the filter in the CROSS APPLY statement.
  • Any time you are trying to join against a table function (this is actually what CROSS APPLY was created for.)

Reference: Add APPLY to Your TSQL Tool Belt from our JCG partner John Sonmez at the Making the Complex Simple.

Related Articles :

Do you want to know how to develop your skillset to become a Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

JPA Mini Book

Learn how to leverage the power of JPA in order to create robust and flexible Java applications. With this Mini Book, you will get introduced to JPA and smoothly transition to more advanced concepts.

JVM Troubleshooting Guide

The Java virtual machine is really the foundation of any Java EE platform. Learn how to master it with this advanced guide!

Given email address is already subscribed, thank you!
Oops. Something went wrong. Please try again later.
Please provide a valid email address.
Thank you, your sign-up request was successful! Please check your e-mail inbox.
Please complete the CAPTCHA.
Please fill in the required fields.

Leave a Reply


+ 8 = thirteen



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy | Contact
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.
Do you want to know how to develop your skillset and become a ...
Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

Get ready to Rock!
You can download the complementary eBooks using the links below:
Close