I have a table in database with numbers of tenants, each tenant lists a record of their sales per date. There are instance where in a tenant has NO SALES in particular date/s, therefore the date with no sales has NO RECORD in the table breaking a proper date sequence. Please see the sample table for illustration below:
I used this select query in sql to display the output above
select tenant, date, sales
from tblSales
where date between '01/01/2015' and '01/05/2014'
What I need as a correct output: display complete date based on the selected date range on the where clause, when tenant has no record in a particular date, the query should add a record of date in that particular tenant and just add null value in the sales column like in this image:
- as my initial solution, I thought of creating a temp table inserting a sequence of date based on the date range selected and use that to left join with the actual table.
Here's what I have started:
@dateFrom datetime = '02/01/2015',
@dateTo date = '02/05/2015'
declare @MaxNumDays int
declare @Counter int
set @Counter = 0
set @MaxNumDays = DATEDIFF(day, @dateFrom , @dateto) + 1
create table #DSRTdate
(
Date datetime
)
WHILE @Counter < @MaxNumDays
BEGIN
insert into #DSRTdate (Date) values (DATEADD(day,@Counter,@dateFrom ))
SET @Counter += 1
END
I used the above codes to get and insert in a temporary table the sequence data from the use selection, in the above case, it inserts 02/01/2015, 02/02/2015, 02/03/2015, 02/04/2015, AND 02/05/2015
select tenantcode, date, sales
into #DSRT2
FROM DAILYMOD
where (date BETWEEN @dateFrom and @dateTo )
SELECT *
from #dsrtdate a left join #DSRT2 b
on a.date = b.date
order by b.tenantcode, a.date
Then i used left join to display the missing dates but this results only to ONE TENANT only and it makes also the tenantname null. like this:
Any suggestion would be highly appreciated.
You could do this using a Tally Table.
Basically, you use the
Tally Table
to generate sequence of dates from@startDate
to@endDate
andCROSS JOIN
it toDISTINCT Item
to generate allDate
-Item
combination. Then, the result will beLEFT-JOIN
ed totblSales
to achieve the desired output.SQL Fiddle
Here is an alternative. Instead of the cascading
CTE
s, usesys.columns
to generate theTally Table
.:Result
I love wewesthemenace answer! Up-voted and have saved it for future reference. Here is another suggestion. Use this code in SQL command from Crystal. Left outer join to your table sales. Its long. Its tedious. But its easier to understand if you aren't an SQL expert which describes me pretty well :) If you figured out his answer and it works then disregard this solution.
Note: the from clause isn't serving any function except to satisfy the requirement of having a from clause in an SQL statement like this. If tblSales is a large table consider using one from your database which has less data and still left outer join to tblSales.