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.

there are no other roll up records for the month, any sales for the day are just rolled up and inserted. On<br />

the second day, however, we have a different scenario: We need to roll up and insert new records as we did<br />

the first day, but we only need to update existing records (for products that have already sold that month).<br />

Let’s take a look at how MERGE can manage both actions in one step. Before we get going on this, however,<br />

we need to create our roll up table:<br />

USE AdventureWorks<strong>2008</strong><br />

CREATE TABLE Sales.MonthlyRollup<br />

(<br />

Year smallint NOT NULL,<br />

Month tinyint NOT NULL,<br />

ProductID int NOT NULL<br />

FOREIGN KEY<br />

REFERENCES Production.Product(ProductID),<br />

QtySold int NOT NULL,<br />

CONSTRAINT PKYearMonthProductID<br />

PRIMARY KEY<br />

(Year, Month, ProductID)<br />

);<br />

This is a pretty simple example of a monthly roll up table making it very easy to get sales totals by product<br />

for a given year and month. To make use of this, however, we need to regularly populate it with<br />

rolled up values from our detail table. To do this, we’ll use MERGE.<br />

First, we need to start by establishing a result set that will figure out from what rows we need to be sourcing<br />

data for our roll up. For purposes of this example, we’ll focus on August of 2003 and start with our query<br />

for the first day of the month:<br />

SELECT soh.OrderDate, sod.ProductID, SUM(sod.OrderQty) AS QtySold<br />

FROM Sales.SalesOrderHeader soh<br />

JOIN Sales.SalesOrderDetail sod<br />

ON soh.SalesOrderID = sod.SalesOrderID<br />

WHERE soh.OrderDate >= ‘2003-08-01’<br />

AND soh.OrderDate < ‘2003-08-02’<br />

GROUP BY soh.OrderDate, sod.ProductID;<br />

This gets us the total sales, by ProductID, for every date in our range (our range just happens to be limited<br />

to one day).<br />

There is a bit of a trap built into how we’ve done this up to this point. I’ve set the GROUP BY to use<br />

the OrderDate, but OrderDate is a datetime data type as opposed to just a date data type. If our orders<br />

were to start coming in with actual times on them, it would mess with our assumption of the orders all<br />

grouping nicely into one date. If this were a production environment, we would want to cast the Order-<br />

Date to a date data type or use DATEPART to assure that the grouping was by day rather than by time.<br />

With this, we’re ready to build our merge:<br />

MERGE Sales.MonthlyRollup AS smr<br />

USING<br />

(<br />

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

207

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

Saved successfully!

Ooh no, something went wrong!