1

I am trying to add a function to my JOIN condition in an MS Access query.

As a simplified example, consider that I have:

tblChildand tblParent and tblGrandparent

tblChild has both a nullable ParentId and GrandparentId depending on which one is known. I'm trying to write a query to take the more specific relationship provided. If this were TSQL it would be:

SELECT
    columns
FROM
    tblChild AS c
LEFT OUTER JOIN
    tblParent AS p
        ON p.[Id] = c.[ParentId]
LEFT OUTER JOIN
    tblGrandparent AS gp
        ON gp.[Id] = COALESE(p.[GrandParentId], c.[GrandParentId])

but I can't figure out how to get a COALESCE style function into the JOIN condition in Access. Here is what I would have expected to work:

SELECT
    columns
FROM
    (tblChild AS c
LEFT OUTER JOIN
    tblParent AS p
        ON p.[Id] = c.[ParentId])
LEFT OUTER JOIN
    tblGrandparent AS gp
        ON gp.[Id] = Nz(p.[GrandParentId], c.[GrandParentId])
Matthew
  • 10,244
  • 5
  • 49
  • 104
  • This should work just fine *Except* that the designer will not know how to represent this. But if you work in SQL view you're good to go. If you switch back to designer and make a change (like add a column) it will rewrite the query from scratch and loose your join. – Brad May 20 '14 at 02:34
  • @Brad I am working exclusively in the SQL view... designer is more of a hassle for me. It doesn't run.... – Matthew May 20 '14 at 02:35
  • It might seem like the designer view is a hassle sometimes but Access has particular syntax it likes and it can be not intuitive if you are used to T-SQL. So using the designer to make the base part of your query (joins, aliases...) can help out. Then once it's made you can switch to SQL view and add in the parts the designer can't so. – Brad May 20 '14 at 02:46
  • **Reopen**, question does not relate to proposed duplicate. This question is about complex joins in Access. – JasonMArcher May 20 '14 at 16:59

1 Answers1

1

I would expect NZ() to work. But can you use or instead?

SELECT columns
FROM (tblChild AS c LEFT JOIN
      tblParent AS p
      ON p.[Id] = c.[ParentId]
     ) LEFT JOIN
    tblGrandparent AS gp
    ON (gp.[Id] = p.[ParentId] or gp.[Id] = c.[GrandParentId]);

This isn't exactly the same. Formally, the last condition would be:

    ON (gp.[Id] = p.[ParentId] or gp.[Id] = c.[GrandParentId] and gp.[Id] <> p.[ParentId]);

EDIT:

Another approach is two joins:

SELECT columns
FROM ((tblChild AS c LEFT JOIN
       tblParent AS p
       ON p.[Id] = c.[ParentId]
      ) LEFT JOIN
     tblGrandparent AS gp
     ON (gp.[Id] = p.[ParentId])
    ) LEFT JOIN
    tblGrandparent AS gp2
    ON gp.[Id] = c.[GrandParentId]);

You then have to adjust the "columns" to pull from either gp or gp2 as appropriate.

Gordon Linoff
  • 1,242,037
  • 58
  • 646
  • 786
  • Doesn't seem to work. I get the same `JOIN expression not supported` – Matthew May 20 '14 at 02:44
  • @Matthew . . . Try removing the `outer`. – Gordon Linoff May 20 '14 at 02:45
  • yes, it does work then. As soon as I add even an ounce of complication it fails. – Matthew May 20 '14 at 02:51
  • two joins approach is actually what I was just trying and it does work, then I will use the `Nz` approach beneath my `SELECT` .... still baffles me though – Matthew May 20 '14 at 02:54
  • The multiple `JOIN` approach is not desirable in my case because I actually have seven layers in this optional hierarchy. If I can use the `Nz` in the `JOIN` condition I just `JOIN` each table once. Using the multiple `JOIN` approach I have to `JOIN` it N times, where N is its level in the hierarchy :( – Matthew May 20 '14 at 02:56