I have an application where the end user may run a report by selecting one or many:
- Customers
- Time Periods
- Metrics
Due to a constraint in my application / reporting platform, I must return a query which contains one row for every combination as selected by the user, even if there is no data for that combination.
I'd like to see if there is any way for me to optimize the query, as I've found it takes quite a lot of time to join the matrix I'm building to the actual financial data to build the data set to be returned.
I've put together a sample as below (SQL Server 2008 R2):
--Average 12 metrics, max 50
declare @Metrics table (MetricID int)
insert into @Metrics values (1000)
insert into @Metrics values (2000)
insert into @Metrics values (3000)
--Average 12 periods, max 24
declare @Periods table (PeriodID int)
insert into @Periods values (201301)
insert into @Periods values (201302)
insert into @Periods values (201303)
--Between 200 and 500 customers
declare @Customers table (CustomerID int)
insert into @Customers values (1)
insert into @Customers values (2)
insert into @Customers values (3)
--Create combined table
declare @IDMatrix table (CustomerID int, PeriodID int, MetricID int)
INSERT INTO @IDMatrix
SELECT x1.CustomerID,
x1.PeriodID,
m.MetricID
FROM (SELECT c.CustomerID, p.PeriodID
FROM @Customers c, @Periods p) x1, @Metrics m
ORDER BY x1.customerid, x1.periodid, m.MetricID
declare @Financials table (CustomerID int, MetricID int, PeriodID int, Value float)
insert into @Financials values (1,1000,201301,984.2)
insert into @Financials values (1,1000,201302,245.1)
insert into @Financials values (1,1000,201303,789.1)
SELECT
i.CustomerID,
i.PeriodID,
i.MetricID,
sum(isnull(f.Value,0))
FROM @IDMatrix i
LEFT JOIN @Financials f ON i.CustomerID = f.CustomerID and i.MetricID = f.MetricID and i.PeriodID = f.PeriodID
GROUP BY
i.CustomerID,
i.PeriodID,
i.MetricID