Reputation: 232
Problem:
let's say i have 3 Common Table Expressions CTE1
, CTE2
, CTE3
.
They all contain MonthID
, YearID
, ProductID
, StoreID
, Amount
I have tables Years
&Months
and YearID
&MonthID
are their Primary Keys.
I need to create a report that contains all the data for given period so i do something like this:
SELECT MonthID, YearID, ProductID, StoreID, Amount
FROM Years
CROSS JOIN Months
CROSS JOIN Products
INNER JOIN Store on Store.StoreId = Products.ProductId
LEFT JOIN CTE1 On CTE1.MonthID = Months.MonthID AND CTE1.YearID = Years AND (CTE1.ProductID = Products.ProductId OR CTE.StoreID = Store.StoreID)
LEFT JOIN CTE2 On CTE2.MonthID = Months.MonthID AND CTE2.YearID = Years AND CTE2.ProductID = Products.ProductId AND CTE2.StoreID = Store.StoreID
LEFT JOIN CTE3 On CTE3.MonthID = Months.MonthID AND CTE3.YearID = Years AND CTE3.ProductID = Products.ProductId AND CTE3.StoreID = Store.StoreID
WHERE CTE1.Amount IS NOT NULL OR CTE2.Amount IS NOT NULL OR CTE3 IS NOT NULL
The thing is in the CTE1
columns StoreID
and ProductID
can be NULL
.
Maybe ProductId
, maybe StoreId
, maybe both columns are NULL
.
And i still need those values to be in my report .... so how do I do it?
Upvotes: 0
Views: 51
Reputation: 35333
Consider using coalesce on the CTE1 value with the join criteria. This way when the CTE1.value is null; the value will be substitued for the value on the other side of the join. The net result is when the CTE1 value is null it basically evaluates to a 1=1 statement and no record would be eliminated.
Granted performance will be sub optimal as you're using a function which may negate index use.
SELECT MonthID, YearID, ProductID, StoreID, Amount
FROM Years
CROSS JOIN Months
CROSS JOIN Products
INNER JOIN Store on Store.StoreId = Products.ProductId
LEFT JOIN CTE1
ON CTE1.MonthID = Months.MonthID
AND CTE1.YearID = Years
AND coalesce(CTE1.ProductID, Products.ProductId) = Products.ProductId
AND coalesce(CTE1.StoreID, Store.StoreID) = Store.StoreID
LEFT JOIN CTE2
On CTE2.MonthID = Months.MonthID
AND CTE2.YearID = Years
AND CTE2.ProductID = Products.ProductId
AND CTE2.StoreID = Store.StoreID
LEFT JOIN CTE3
On CTE3.MonthID = Months.MonthID
AND CTE3.YearID = Years
AND CTE3.ProductID = Products.ProductId
AND CTE3.StoreID = Store.StoreID
WHERE CTE1.Amount IS NOT NULL
OR CTE2.Amount IS NOT NULL
OR CTE3 IS NOT NULL
Upvotes: 1