tags:

views:

109

answers:

1

I have a table that logs inventory updates throughout the day.

Table InventoryHistory:

UpdateID INT IDENTITY
ProductID INT
UpdateDateTime DATETIME
QuantityOnHand INT

Sample records:

1, 1, '7/29/2009 9:00', 100
2, 1, '7/29/2009 14:00', 99
3, 1, '7/29/2009 20:00', 98
4, 1, '7/30/2009 9:00', 97

For a given ProductID, I need to get a row returned for each day for the last 30 days which has the last update BEFORE 5PM for that given day.

So, the results for productid = 1 should be:

2, 1, '7/29/2009 14:00', 99
4, 1, '7/30/2009 9:00', 97

I've tried building a temp table with the last 30 days in it, and then a subquery against that, but I've been running in circles for hours, and I'm trying to find an elegant solution (without using CURSORS).

Help!

+3  A: 

how about trying a CTE with a partitioned row number (SQL 2005 & newer)...

WITH MyCte AS (SELECT  *,
                       RowNum = ROW_NUMBER() OVER (PARTITION BY CONVERT(CHAR(8), UpdateDateTime, 112) ORDER BY UpdateDateTime DESC ) 
               FROM    InventoryHistory
               WHERE   UpdateDateTime >= convert(char(8), dateadd(yy, -30, getdate()), 112)
                       AND DATEPART(hh, UpdateDateTime) < 17)
SELECT   UpdateID, 
         ProductID, 
         UpdateDateTime, 
         QuantityOnHand 
FROM     MyCte
WHERE    RowNum = 1


/* Results 
UpdateID    ProductID   UpdateDateTime          QuantityOnHand
----------- ----------- ----------------------- --------------
2           1           2009-07-29 14:00:00.000 99
4           1           2009-07-30 09:00:00.000 97

(2 row(s) affected)
*/
Scott Ivey
works fine, provided the OP is on SQL Server 2005 and up - won't work in SQL Server 2000 :-(
marc_s
sure - but considering how old SQL 2000 is, one should specify that they are running on an old version when asking a question ;)
Scott Ivey
This worked perfectly! (And I'm on SQL 2008, which is why I didn't bother mentioning it). Thanks so much for your help!
khutch