IMO - To clarify the outer/inner join issue
when you put a select criteria on an outer joined table it applies the filter after the join was made and the joined data set was 'created'. It is not necessarily the same as an inner join.
the inner join only selects items where the fields are matched on both tables .
the outer join selects all records from table 1 and only matching records from table 2.
If you then place a WHERE onto the outer join data set (use the select expert) it will often filter out items you were trying to get at in the outer join process but not necessarily all of them.
if you move the condition onto the outer join itself it alleviates the problem. You would need to use a command object or a stored proc to achieve this.
Z has a reasonable approach but I think you will still need to do some manuevering to display NULL address types. likely doing a grouping and a GFa and GFb to show the two address types