20.07.2013 Views

Beginning SQL

Beginning SQL

Beginning SQL

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

Chapter 9<br />

282<br />

MemberDetails.FirstName,<br />

MemberDetails.LastName,<br />

COUNT(*) - 1<br />

FROM (Orders INNER JOIN MemberDetails<br />

ON Orders.MemberId = MemberDetails.MemberId)<br />

INNER JOIN SalesPerson<br />

ON Orders.SalesPersonId = SalesPerson.SalesPersonId<br />

GROUP BY SalesPerson.SalesPersonId,<br />

SalesPerson.FirstName,<br />

SalesPerson.LastName,<br />

MemberDetails.MemberId,<br />

MemberDetails.FirstName,<br />

MemberDetails.LastName<br />

HAVING COUNT(Orders.MemberId) > 1<br />

ORDER BY SalesPerson.SalesPersonId<br />

There’s very often more than one way to write a query. This section shows you one alternative way of<br />

writing the same query you wrote in the previous Try It Out, though there may be even more ways. This<br />

alternative way uses a self-join, with the Orders table joined to itself. Consider the following statement:<br />

SELECT SalesPerson.SalesPersonId,<br />

SalesPerson.FirstName,<br />

SalesPerson.LastName,<br />

MemberDetails.MemberId,<br />

MemberDetails.FirstName,<br />

MemberDetails.LastName,<br />

COUNT(*) AS “Repeat Orders”<br />

FROM ((Orders O1 INNER JOIN Orders O2<br />

ON O1.MemberId = O2.MemberId AND O1.SalesPersonId = O2.SalesPersonId<br />

AND O1.OrderId > O2.OrderId)<br />

INNER JOIN MemberDetails<br />

ON O1.MemberId = MemberDetails.MemberId)<br />

INNER JOIN SalesPerson<br />

ON O1.SalesPersonId = SalesPerson.SalesPersonId<br />

GROUP BY SalesPerson.SalesPersonId,<br />

SalesPerson.FirstName,<br />

SalesPerson.LastName,<br />

MemberDetails.MemberId,<br />

MemberDetails.FirstName,<br />

MemberDetails.LastName<br />

ORDER BY SalesPerson.SalesPersonId;<br />

The SELECT column list is virtually identical, except that repeat order values are now obtained using<br />

COUNT(*), whereas before they were obtained with COUNT(*) – 1. The reason for this change is that<br />

this query, you see shortly, returns only the repeat orders and not the first order placed by a member.<br />

Also, because of this change, you don’t need a HAVING clause that limits records where each group has<br />

more than one member.<br />

The difference between this query and the query you previously wrote is in the FROM clause and its use<br />

of a self-join. The Orders table is joined to itself, the first table being given an alias of O1 and the second<br />

an alias of O2. The MemberId and SalesPersonId columns are joined on the basis of being the same, and<br />

the OrderDate column is joined on the basis of O1’s OrderDate being after O2’s, which ensures that only<br />

the repeat orders are included. If there’s only one order, then clearly O1.OrderDate can never be higher<br />

than O2.OrderDate, as the order in O2 is the same record with identical values.

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

Saved successfully!

Ooh no, something went wrong!