Beginning Microsoft SQL Server 2008 ... - S3 Tech Training

Beginning Microsoft SQL Server 2008 ... - S3 Tech Training Beginning Microsoft SQL Server 2008 ... - S3 Tech Training

cdn.s3techtraining.com
from cdn.s3techtraining.com More from this publisher
17.06.2013 Views

Chapter 7: Adding More to Our Queries As you can see, we were able to take a seemingly impossible query and make it both possible and even reasonably well performing. Keep in mind that derived tables aren’t the solutions for everything. For example, if the result set is going to be fairly large and you’re going to have lots of joined records, then you may want to look at using a temporary table and building an index on it (derived tables have no indexes). Every situation is different, but now you have one more weapon in your arsenal. The EXISTS Operator 200 I call EXISTS an operator, but Books Online calls it a keyword. That’s probably because it defies description in some senses. It’s an operator much like the IN keyword is, but it also looks at things just a bit differently. When you use EXISTS, you don’t really return data — instead, you return a simple TRUE/FALSE regarding the existence of data that meets the criteria established in the query that the EXISTS statement is operating against. Let’s go right to an example, so you can see how this gets applied. What we’re going to query here is a list of persons who are employees: SELECT BusinessEntityID, LastName + ', ' + FirstName AS Name FROM Person.Person pp WHERE EXISTS (SELECT BusinessEntityID FROM HumanResources.Employee hre WHERE hre.BusinessEntityID = pp.BusinessEntityID); As we might expect, this gets us a relatively small subset of our Person table — 290 of them: BusinessEntityID Name ---------------- ---------------------------------------------------------- 263 Trenary, Jean 78 D'sa, Reuben 242 Poe, Deborah … … 95 Scardelis, Jim 215 Harrington, Mark 112 Evans, John (290 row(s) affected) We could have easily done this same thing with a join: SELECT pp.BusinessEntityID, LastName + ', ' + FirstName AS Name FROM Person.Person pp JOIN HumanResources.Employee hre ON pp.BusinessEntityID = hre.BusinessEntityID;

This join-based syntax, for example, would have yielded exactly the same results (subject to possible sort differences). So why, then, would we need this new syntax? Performance — plain and simple. When you use the EXISTS keyword, SQL Server doesn’t have to perform a full row-by-row join. Instead, it can look through the records until it finds the first match and stop right there. As soon as there is a single match, the EXISTS is true, so there is no need to go further. Let’s take a brief look at things the other way around — that is, what if our query wanted the persons who were not employees? Under the join method that we looked at in Chapter 4, we would have had to make some significant changes in the way we went about getting our answers. First, we would have to use an outer join. Then we would perform a comparison to see whether any of the Employee records were NULL. It would look something like this: SELECT pp.BusinessEntityID, LastName + ', ' + FirstName AS Name FROM Person.Person pp LEFT JOIN HumanResources.Employee hre ON pp.BusinessEntityID = hre.BusinessEntityID WHERE hre.BusinessEntityID IS NULL; Which returns 19,682 rows: BusinessEntity ID Name -------------- ------------------------------------------------------------------ 293 Abel, Catherine 295 Abercrombie, Kim 2170 Abercrombie, Kim … … 2088 Zugelder, Judy 12079 Zukowski, Jake 2089 Zwilling, Michael (19682 row(s) affected) To do the same change over when we’re using EXISTS, we add only one word to the original EXIST query — NOT: SELECT BusinessEntityID, LastName + ', ' + FirstName AS Name FROM Person.Person pp WHERE NOT EXISTS (SELECT BusinessEntityID FROM HumanResources.Employee hre WHERE hre.BusinessEntityID = pp.BusinessEntityID); And we get back those exact same 19,682 rows. Chapter 7: Adding More to Our Queries The performance difference here is, in most cases, even more marked than with the inner join. SQL Server just applies a little reverse logic versus the straight EXISTS statement. In the case of the NOT we’re now using, SQL can still stop looking as soon as it finds one matching record — the only difference is 201

This join-based syntax, for example, would have yielded exactly the same results (subject to possible sort<br />

differences). So why, then, would we need this new syntax? Performance — plain and simple.<br />

When you use the EXISTS keyword, <strong>SQL</strong> <strong>Server</strong> doesn’t have to perform a full row-by-row join. Instead, it<br />

can look through the records until it finds the first match and stop right there. As soon as there is a single<br />

match, the EXISTS is true, so there is no need to go further.<br />

Let’s take a brief look at things the other way around — that is, what if our query wanted the persons<br />

who were not employees? Under the join method that we looked at in Chapter 4, we would have had<br />

to make some significant changes in the way we went about getting our answers. First, we would have to<br />

use an outer join. Then we would perform a comparison to see whether any of the Employee records<br />

were NULL.<br />

It would look something like this:<br />

SELECT pp.BusinessEntityID, LastName + ', ' + FirstName AS Name<br />

FROM Person.Person pp<br />

LEFT JOIN HumanResources.Employee hre<br />

ON pp.BusinessEntityID = hre.BusinessEntityID<br />

WHERE hre.BusinessEntityID IS NULL;<br />

Which returns 19,682 rows:<br />

BusinessEntity ID Name<br />

-------------- ------------------------------------------------------------------<br />

293 Abel, Catherine<br />

295 Abercrombie, Kim<br />

2170 Abercrombie, Kim<br />

…<br />

…<br />

2088 Zugelder, Judy<br />

12079 Zukowski, Jake<br />

2089 Zwilling, Michael<br />

(19682 row(s) affected)<br />

To do the same change over when we’re using EXISTS, we add only one word to the original EXIST<br />

query — NOT:<br />

SELECT BusinessEntityID, LastName + ', ' + FirstName AS Name<br />

FROM Person.Person pp<br />

WHERE NOT EXISTS<br />

(SELECT BusinessEntityID<br />

FROM HumanResources.Employee hre<br />

WHERE hre.BusinessEntityID = pp.BusinessEntityID);<br />

And we get back those exact same 19,682 rows.<br />

Chapter 7: Adding More to Our Queries<br />

The performance difference here is, in most cases, even more marked than with the inner join. <strong>SQL</strong><br />

<strong>Server</strong> just applies a little reverse logic versus the straight EXISTS statement. In the case of the NOT we’re<br />

now using, <strong>SQL</strong> can still stop looking as soon as it finds one matching record — the only difference is<br />

201

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!