17.06.2013 Views

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

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

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

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

What if we want to place conditions on what the groups themselves look like? In other words, what if<br />

we want every row to be added to a group, but then we want to say that only after the groups are fully<br />

accumulated are we ready to apply the condition. Well, that’s where the HAVING clause comes in.<br />

The HAVING clause is used only if there is also a GROUP BY in your query. Whereas the WHERE clause is<br />

applied to each row before it even has a chance to become part of a group, the HAVING clause is applied to<br />

the aggregated value for that group.<br />

Let’s start off with a slight modification to the GROUP BY query we used at the end of the previous section —<br />

the one that tells us the number of employees assigned to each manager’s EmployeeID:<br />

SELECT ManagerID AS Manager, COUNT(*) AS Reports<br />

FROM HumanResources.Employee2<br />

GROUP BY ManagerID;<br />

In the next chapter, we’ll learn how to put names on the EmployeeIDs that are in the Manager column.<br />

For now though, we’ll just note that there appear to be three different managers in the company. Apparently,<br />

everyone reports to these three people, except for one person who doesn't have a manager assigned —<br />

that is probably our company president (we could write a query to verify that, but we'll just trust in our<br />

assumptions for now).<br />

We didn’t put a WHERE clause in this query, so the GROUP BY was operating on every row in the table and<br />

every row is included in a grouping. To test what would happen to our COUNTs, let’s add a WHERE clause:<br />

SELECT ManagerID AS Manager, COUNT(*) AS Reports<br />

FROM HumanResources.Employee2<br />

WHERE EmployeeID != 5<br />

GROUP BY ManagerID;<br />

This yields one slight change that may be somewhat different than expected:<br />

Manager Reports<br />

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

NULL 1<br />

1 3<br />

4 2<br />

5 4<br />

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

Chapter 3: The Foundation Statements of T-<strong>SQL</strong><br />

No rows were eliminated from the result set, but the result for ManagerID 4 was decreased by one (what<br />

the heck does this have to do with ManagerID 5?). You see, the WHERE clause eliminated the one row<br />

where the EmployeeID was 5. As it happens, EmployeeID 5 reports to ManagerID 4, so the total for<br />

ManagerID 4 was one less (EmployeeID 5 is no longer counted for this query). ManagerID 5 was not<br />

affected, as we eliminated him or her as a report (as an EmployeeID) rather than as a manager. The key<br />

thing here is to realize that EmployeeID 5 was eliminated before the GROUP BY was applied.<br />

I want to look at things a bit differently though. See if you can work out how to answer the following<br />

question. Which managers have more than three people reporting to them? You can look at the query<br />

without the WHERE clause and tell by the COUNT, but how do you tell programmatically? That is, what if<br />

we need this query to return only the managers with more than three people reporting to them? If you<br />

try to work this out with a WHERE clause, you’ll find that there isn’t a way to return rows based on the<br />

63

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

Saved successfully!

Ooh no, something went wrong!