Skip to main content
Announcements
Global Transformation Awards! Applications are now open. Submit Entry
cancel
Showing results for 
Search instead for 
Did you mean: 
MikeH1983
Contributor III
Contributor III

How to Join with 'filling in' of missing values

Hi everyone, hoping someone can help me with this one.

I am trying to join two tables of people, month end dates and facts, where the fact table does not have a complete date set. I want to fill in 0 for dates where there is no entry on the fact table.

I normally join tables with a Left Join, and then load a result table where the dates are equal:

Left Join (Table1) 
 Load *
Resident Table2;

ResultTable:

NOCONCATENATE Load *

Resident Table1

Where FactMonthEnd = MonthEnd

However I cannot figure out how to insert the zeros. This script excludes the dates for which there is no Fact value, but I need a full date set since I am adding other data.

Here is my desired result below. Can anyone help me? If the solution is to expand the FactTable and insert the zeros there, can you suggest a way I can do that instead? Thanks very much.

Table1:  Table2:   ResultTable:  
PersonMonthEnd PersonFactMonthEndFact PersonMonthEndFact
12018-01-31 12018-01-3110 12018-01-3110
12018-02-28 12018-03-3110 12018-02-280
12018-03-31 12018-05-3140 12018-03-3110
12018-04-30 22018-02-2820 12018-04-300
12018-05-31 22018-04-3020 12018-05-3140
12018-06-30 22018-06-3010 12018-06-300
22018-01-31     22018-01-310
22018-02-28     22018-02-2820
22018-03-31     22018-03-310
22018-04-30     22018-04-3020
22018-05-31     22018-05-310
22018-06-30     22018-06-3010
Labels (2)
1 Solution

Accepted Solutions
MikeH1983
Contributor III
Contributor III
Author

I took a different approach to solve this problem. I cartesian joined all the FactMonthEnds and Facts to all of the MonthEnds, and took a Sum in a new table that picked up where these were the same date (and would thus generate 0 when there was no aligned date). I have used this same technique before to aggregate monthly absence data in the script. My method:

I copied Table1 to create Table1B.

I joined the Table2 Fact table to Table1, with no common field (FactMonthEnd is a different field name), so a cartesian join.

I created a table MonthValues:

NOCONCATENATE Load Distinct

Person,

MonthEnd as SumMonthEnd,

Sum(if(FactMonthEnd =MonthValueDate,Fact)) as FactValue

Resident Table1
Group By [Person],MonthEnd;

Then I cartesian joined this back to Table1B

Left Join (Table1B
 Load
 [Person],
    FactValue,
    SumMonthEnd 
    Resident MonthValues;

Then I filtered this down in a FinalTable where SumMonthEnd = MonthEnd

FinalTable:

  NOCONCATENATE Load
    [Person],
    MonthEnd,
    FactValue    
    Resident Table1B
    Where SumMonthEnd = MonthEnd or isnull(SumMonthEnd); 

 

View solution in original post

2 Replies
Gabriel
Partner - Specialist III
Partner - Specialist III

Hi,

 

I have similar issue in one of my application.

My solution was,

  1. Find and createnfull date MinDate to MaxDate in your script. Find the min & max from the main table.
  2. Create another table with the field  you wanted to populate with zeros (0)
  3. OUTRT JOIN the full date table with the new table in step 2 above
  4. Now OUTER JOIN the new table which contain the full date with zero table created in step 3 to the main table you started with.

See my blog post for the solution

 

Hope it helps

MikeH1983
Contributor III
Contributor III
Author

I took a different approach to solve this problem. I cartesian joined all the FactMonthEnds and Facts to all of the MonthEnds, and took a Sum in a new table that picked up where these were the same date (and would thus generate 0 when there was no aligned date). I have used this same technique before to aggregate monthly absence data in the script. My method:

I copied Table1 to create Table1B.

I joined the Table2 Fact table to Table1, with no common field (FactMonthEnd is a different field name), so a cartesian join.

I created a table MonthValues:

NOCONCATENATE Load Distinct

Person,

MonthEnd as SumMonthEnd,

Sum(if(FactMonthEnd =MonthValueDate,Fact)) as FactValue

Resident Table1
Group By [Person],MonthEnd;

Then I cartesian joined this back to Table1B

Left Join (Table1B
 Load
 [Person],
    FactValue,
    SumMonthEnd 
    Resident MonthValues;

Then I filtered this down in a FinalTable where SumMonthEnd = MonthEnd

FinalTable:

  NOCONCATENATE Load
    [Person],
    MonthEnd,
    FactValue    
    Resident Table1B
    Where SumMonthEnd = MonthEnd or isnull(SumMonthEnd);