Solved

Return 0 for hours with no sales

Posted on 2009-07-07
10
270 Views
Last Modified: 2012-05-07
I've got the following query:


SELECT DATEPART(hour, TimeStamp) AS Hour
, SUM(cast(Amount as money)) AS Sales
FROM billingTransactions
WHERE DATEADD(day, 0, DATEDIFF(day, 0, TimeStamp)) = '07/06/2009'
GROUP BY DATEPART(hour, TimeStamp)
ORDER BY hour

I want it to return a 0 for hours where there are no sales.....  This works well, but only returns those hours with actual sales.
0
Comment
Question by:pazzaTim
  • 3
  • 3
  • 2
10 Comments
 
LVL 75

Expert Comment

by:Aneesh Retnakaran
Comment Utility
;with cte (i) as (
Select 1 as i
union all
select i+1 as i
from cte )

SELECT i AS Hour
, ISNULL( SUM(cast(Amount as money)),0) AS Sales
FROM billingTransactions
LEFT Join CTE c ON c.i = DATEPART(hour, TimeStamp)
WHERE DATEADD(day, 0, DATEDIFF(day, 0, TimeStamp)) = '07/06/2009'
GROUP BY DATEPART(hour, TimeStamp)
order by hour
OPTION (MAXRECURSION 24)
0
 

Author Comment

by:pazzaTim
Comment Utility
Not working... First it said that cte.i not in group by, when I added it, we got max recursions...
0
 

Author Comment

by:pazzaTim
Comment Utility
The statement terminated. The maximum recursion 24 has been exhausted before statement completion.
0
 
LVL 75

Accepted Solution

by:
Aneesh Retnakaran earned 250 total points
Comment Utility
instead of cte you can populate a temptable with 24 hours and you juts need to join that table

SELECT i AS Hour
, ISNULL( SUM(cast(Amount as money)),0) AS Sales
FROM billingTransactions
LEFT Join @tempTable  c ON c.i = DATEPART(hour, TimeStamp)
WHERE DATEADD(day, 0, DATEDIFF(day, 0, TimeStamp)) = '07/06/2009'
GROUP BY DATEPART(hour, TimeStamp)
order by hour
OPTION (MAXRECURSION 24)
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 

Author Comment

by:pazzaTim
Comment Utility
SELECT CTE.HR, ISNULL(SS.TOTAL,0) AS TOTAL
FROM (
SELECT DISTINCT DATEPART(hour, TimeStamp) AS HR
FROM billingTransactions
) CTE
LEFT OUTER JOIN (
SELECT DATEPART(hour, TimeStamp) AS HR, SUM(CAST(Amount AS money)) AS TOTAL
FROM billingTransactions
WHERE DATEADD(day, 0, DATEDIFF(day, 0, TimeStamp)) = '07/06/2009'
GROUP BY DATEPART(hour, TimeStamp)
) SS
ON CTE.HR = SS.HR
order by hr
0
 
LVL 14

Assisted Solution

by:rob_farley
rob_farley earned 250 total points
Comment Utility
If you were to archive off most of your records in billingTransactions, you'll find this no longer produces all your hours.

So why not go with:

WITH AllHours AS (
SELECT 0 AS Hour
UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5
UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9 UNION ALL SELECT 10
UNION ALL SELECT 11 UNION ALL SELECT 12 UNION ALL SELECT 13 UNION ALL SELECT 14 UNION ALL SELECT 15
UNION ALL SELECT 16 UNION ALL SELECT 17 UNION ALL SELECT 18 UNION ALL SELECT 19 UNION ALL SELECT 20
UNION ALL SELECT 21 UNION ALL SELECT 22 UNION ALL SELECT 23)
SELECT H.Hour, SS.Total
FROM AllHours H
  LEFT OUTER JOIN (
SELECT DATEPART(hour, TimeStamp) AS HR, SUM(Amount) AS Total
FROM billingTransactions
WHERE TimeStamp >= '20090706' AND TimeStamp < '20090707'
GROUP BY DATEPART(hour, TimeStamp)
) SS
ON H.Hour = SS.HR
ORDER BY H.Hour;

You'll also notice that I have changed the WHERE clause, so that I'm not fiddling with the TimeStamp column. This means that a non-clustered index like:

create index ixTimeStampAmont on billingTransactions(TimeStamp) include (Amount);

...will make this query much faster.

Also, the ORDER BY is now specifying a table alias, to make sure there's no ambiguity.

Hope this helps complete the picture...

Rob
0
 
LVL 14

Expert Comment

by:rob_farley
Comment Utility
pazzaTim should assign some points here...
0
 
LVL 14

Expert Comment

by:rob_farley
Comment Utility
I think if pazzaTim found that the answer he wrote was the best, then it's fine to Accept that one as the answer, but as the Asker, he should've given the points to those that helped.

So... Accept with 50, and give 450 away to the other experts who contributed.

Rob
0

Featured Post

What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

Join & Write a Comment

Ever needed a SQL 2008 Database replicated/mirrored/log shipped on another server but you can't take the downtime inflicted by initial snapshot or disconnect while T-logs are restored or mirror applied? You can use SQL Server Initialize from Backup…
Shadow IT is coming out of the shadows as more businesses are choosing cloud-based applications. It is now a multi-cloud world for most organizations. Simultaneously, most businesses have yet to consolidate with one cloud provider or define an offic…
Video by: Steve
Using examples as well as descriptions, step through each of the common simple join types, explaining differences in syntax, differences in expected outputs and showing how the queries run along with the actual outputs based upon a simple set of dem…
Polish reports in Access so they look terrific. Take yourself to another level. Equations, Back Color, Alternate Back Color. Write easy VBA Code. Tighten space to use less pages. Launch report from a menu, considering criteria only when it is filled…

763 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now