|
|
|
SSC Veteran
      
Group: General Forum Members
Last Login: Today @ 9:22 AM
Points: 223,
Visits: 284
|
|
kevriley (9/28/2009) Mark,
when I run your code I get some CPU and more logical reads - have you tried on a clean 'server'
i.e after restarting or running dbcc dropcleanbuffers & dbcc freeproccache
[please don't run these on a live production server]
Kev
Kev:
Yes, I did. The results I posted were running from an x86 desktop running SQL Express 2008. I put the sample table/data and my SQL statement on a 2005 development instance (dedicated SQL machine with 4 instances and >= 100 active connections) and got the following:
(391 row(s) affected) Table 'DailySalesTotals'. Scan count 1, logical reads 15, physical reads 0, read-ahead reads 46, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
SQL Server Execution Times: CPU time = 15 ms, elapsed time = 7 ms.
I have not tried restarting the SQL service on the desktop so I don't have a true "clean" server reading. Out of curiosity, what were your results?
MJM
|
|
|
|
|
SSCrazy
      
Group: General Forum Members
Last Login: Monday, May 13, 2013 12:01 PM
Points: 2,677,
Visits: 2,273
|
|
Your results:
(391 row(s) affected) Table 'DailySalesTotals'. Scan count 1, logical reads 12, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
(1 row(s) affected)
SQL Server Execution Times: CPU time = 16 ms, elapsed time = 33ms.
versus Joe's original :
(391 row(s) affected) Table 'DailySalesTotals'. Scan count 921, logical reads 1853, physical reads 2, read-ahead reads 14, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
(1 row(s) affected)
SQL Server Execution Times: CPU time = 15 ms, elapsed time = 29 ms
These running on SQL 2008 SP1 Developer Edition, on a Intel Core 2 Duo (1.86GHz), 1.5 GB RAM (i.e. personal dev environment on spare PC)
I was just so surprised you didn't even see any CPU!!
Kev
|
|
|
|
|
Forum Newbie
      
Group: General Forum Members
Last Login: Friday, October 02, 2009 11:45 AM
Points: 1,
Visits: 4
|
|
I've gone for a solution that will work in any version of SQL Server. It will also give more information, as in reality, the sales Dept will want to know by how much it dropped and when the previous order was. It runs at exactly the same speed as Chris's solution on my machine. In order to comply with the competition, I've used Joe's original result and commented out my 'improved' version.
SELECT CustomersLastTwoDates.customer_ID, 'dropped purchase amount on', lastOrderDate /* CustomersLastTwoDates.customer_ID, 'dropped purchase amount by', previous.order_amt-CustomersLastTwoDates.order_amt, 'between', previous.order_date, 'and', lastOrderDate */ FROM (SELECT lastone.customer_ID, lastone.order_date AS lastOrderDate, lastone.order_amt, DATEADD(DAY, -MIN(DATEDIFF(DAY,d.order_Date,lastone.order_date)), lastone.order_date)AS penultimateOrderDate FROM DailySalesTotals d INNER JOIN (SELECT latest.customer_id, latest.order_date, latest.order_amt FROM DailySalesTotals latest INNER JOIN (SELECT customer_ID, [order_date] = MAX(Order_Date) FROM DailySalesTotals GROUP BY customer_ID) lastPurchase ON latest.customer_ID= lastPurchase.customer_ID AND latest.order_Date=lastPurchase.order_date) lastone ON lastone.customer_ID= d.customer_ID AND lastone.order_Date> d.order_date GROUP BY lastone.customer_ID, lastone.order_date,lastone.order_amt HAVING MIN(lastone.order_amt-d.order_amt)<0 ) CustomersLastTwoDates INNER JOIN DailySalesTotals previous ON previous.customer_ID =CustomersLastTwoDates.customer_ID AND previous.order_Date=CustomersLastTwoDates.penultimateOrderDate WHERE CustomersLastTwoDates.order_amt < previous. order_amt
Ed: entry copied from Simple-Talk's version of the competition
|
|
|
|
|
Mr or Mrs. 500
      
Group: General Forum Members
Last Login: Sunday, May 19, 2013 4:00 AM
Points: 533,
Visits: 2,285
|
|
I've put all entrants so far into a test harness on my dev. server. They all give the same results, They all run at about the same speed. Typical results are:
16ms Chris Howarth 16ms Celko 13ms Wm Brewer 16ms Mark Marinovic 46ms GSquared 16ms Peter Brinkhaus 30ms back_of_the_fleet
Although this is too short a time to be seriously measurable, I'd say that all but GSquared's routine run at approx the same speed. The table size is too small. I'll try a re-run with a larger sample. However, I reckon Joe isn't going to be focussed solely on performance in judging the solution, certainly when the entries are so closely matched, and it seems a bit unfair to judge on a table size different to the one we supplied. However, scalablilty is going to be an interesting factor to look at!
Best wishes,
Phil Factor Simple Talk
|
|
|
|
|
SSC-Insane
         
Group: General Forum Members
Last Login: Today @ 10:15 PM
Points: 21,615,
Visits: 27,448
|
|
|
|
|
|
SSC Veteran
      
Group: General Forum Members
Last Login: Wednesday, May 08, 2013 3:01 AM
Points: 266,
Visits: 1,023
|
|
|
|
|
|
Mr or Mrs. 500
      
Group: General Forum Members
Last Login: Sunday, May 19, 2013 4:00 AM
Points: 533,
Visits: 2,285
|
|
No, this is open to all. Hopefully, (and it was our original intention) those with only 2005 will be at no disadvantage and even if you only have 2000, you should be able to compete. (It looks as if William's, for example will run on almost anything, and eliminates the nested subqueries that Joe didn't like in his original solution.) Yeah: we messed up slightly w1th the rules, which were taken for Joe's original generic rules for the stumpers. Blush.
Best wishes,
Phil Factor Simple Talk
|
|
|
|
|
SSC Veteran
      
Group: General Forum Members
Last Login: Wednesday, May 08, 2013 3:01 AM
Points: 266,
Visits: 1,023
|
|
Not sure if a second entry is allowed, but here's another version that uses pivoting, this time using SQL Server's PIVOT keyword.
Again the values of the most recent two orders are transposed before being compared:
SELECT customer_id, ' dropped purchase amount on ', MAX(order_date) FROM ( SELECT ROW_NUMBER() OVER(PARTITION BY customer_id ORDER BY order_date DESC) AS RowNumber, customer_id, order_date, order_amt FROM DailySalesTotals ) AS st PIVOT (SUM(order_amt) FOR RowNumber IN ([1],[2]) ) AS PivotTable GROUP BY customer_id HAVING MAX([1]) < MAX([2]) ORDER BY customer_id As with the other pivoted examples a single table scan is performed.
Chris
|
|
|
|
|
SSC Rookie
      
Group: General Forum Members
Last Login: Tuesday, April 30, 2013 6:16 AM
Points: 43,
Visits: 268
|
|
I didn't check to see if this has already been submitted, but here goes:
WITH SalesOrder AS ( SELECT Customer_id, Order_date, Order_amt, ROW_NUMBER() OVER (PARTITION BY Customer_ID ORDER BY order_date DESC) AS SalesOrder FROM DailySalesTotals ) SELECT S1.Customer_id, ' dropped purchase amount on ', S1.Order_date FROM SalesOrder AS S1 INNER JOIN SalesORder AS S2 ON S2.Customer_id = S1.Customer_id WHERE S1.SalesOrder = 1 AND S2.SalesOrder = 2 AND S1.Order_amt < S2.Order_amt
|
|
|
|
|
Forum Newbie
      
Group: General Forum Members
Last Login: Thursday, March 31, 2011 6:43 AM
Points: 3,
Visits: 33
|
|
| I have some code to post. But first I wanted to ask - how do you test the CPU time and logical reads? Sorry for my ignorance.
|
|
|
|