I feel like I’ve seen this question asked before, but neither the SO search nor google is helping me… maybe I just don’t know how to phrase the question. I need to count the number of events (in this case, logins) per day over a given time span so that I can make a graph of website usage. The query I have so far is this:
select count(userid) as numlogins, count(distinct userid) as numusers, convert(varchar, entryts, 101) as date from usagelog group by convert(varchar, entryts, 101)
This does most of what I need (I get a row per date as the output containing the total number of logins and the number of unique users on that date). The problem is that if no one logs in on a given date, there will not be a row in the dataset for that date. I want it to add in rows indicating zero logins for those dates. There are two approaches I can think of for solving this, and neither strikes me as very elegant.
- Add a column to the result set that lists the number of days between the start of the period and the date of the current row. When I’m building my chart output, I’ll keep track of this value and if the next row is not equal to the current row plus one, insert zeros into the chart for each of the missing days.
- Create a ‘date’ table that has all the dates in the period of interest and outer join against it. Sadly, the system I’m working on already has a table for this purpose that contains a row for every date far into the future… I don’t like that, and I’d prefer to avoid using it, especially since that table is intended for another module of the system and would thus introduce a dependency on what I’m developing currently.
Any better solutions or hints at better search terms for google? Thanks.
Frankly, I’d do this programmatically when building the final output. You’re essentially trying to read something from the database which is not there (data for days that have no data). SQL isn’t really meant for that sort of thing.
If you really want to do that, though, a ‘date’ table seems your best option. To make it a bit nicer, you could generate it on the fly, using i.e. your DB’s date functions and a derived table.