I have four tables in Access 2010, each with the same primary key. I'd like to join all the data in all four tables into one table with columns for each value tied to the primary key over all the tables. So, for example:
Table1
ID Value1
1 10
2 7
3 4
4 12
Table 2
ID Value2
1 33
2 8
6 19
7 4
Table 3
ID Value3
1 99
2 99
5 99
7 99
I'd like to create:
Table 4
ID Value1 Value2 Value3
1 10 33 99
2 7 8 99
3 4
4 12
5 99
6 19
7 4 99
I'm using MS Access and I know I have to basically use 3 joins (left, right, inner) to get a full join, but I'm not exactly sure about how to structure the query.
Could someone please give me some example SQL code to point me in the right direction as to how to produce this result?
Here is what I have so far. This combines all the tables, but it looks like I'm still missing some data. Have I done something wrong:
SELECT Coventry.cptcode, Coventry.[Fee Schedule], CT6002.[Fee Schedule], Medicare.[Fee Schedule], OFSP.[Fee Schedule]
FROM ((Coventry LEFT JOIN CT6002 ON Coventry.cptcode = CT6002.cptcode) LEFT JOIN Medicare ON CT6002.cptcode = Medicare.cptcode) LEFT JOIN OFSP ON Medicare.cptcode = OFSP.cptcode
UNION
SELECT Coventry.cptcode, Coventry.[Fee Schedule], CT6002.[Fee Schedule], Medicare.[Fee Schedule], OFSP.[Fee Schedule]
FROM ((Coventry RIGHT JOIN CT6002 ON Coventry.cptcode = CT6002.cptcode) RIGHT JOIN Medicare ON CT6002.cptcode = Medicare.cptcode) RIGHT JOIN OFSP ON Medicare.cptcode = OFSP.cptcode
UNION
SELECT Coventry.cptcode, Coventry.[Fee Schedule], CT6002.[Fee Schedule], Medicare.[Fee Schedule], OFSP.[Fee Schedule]
FROM ((Coventry INNER JOIN CT6002 ON Coventry.cptcode = CT6002.cptcode) INNER JOIN Medicare ON CT6002.cptcode = Medicare.cptcode) INNER JOIN OFSP ON Medicare.cptcode = OFSP.cptcode;
How about this?
How it works:
Rather than doing a join, I put all of the results into one "table" (my sub query), but with value1, value2 and value3 in their own columns, and set to null for the tables that don't have those columns.
The
iif
statements in the first query are to say that I want v2 and v3 to be the same data type as v1. It's a dodgy hack but seems to work (sadly access works out the type from the first statement in the query, and casting withclng(null)
didn't work). They work because the result of the iif must be of the same type as the last two parameters, and only the last parameter has a type, so that gets inferred from this; whilst the first parameter being true means that the value returned will only ever be the second parameter.The outer query then squashes these results down to one line per id; since fields with a value are greater than null and we have at most one field with a value per id, we get that value for that column.
I'm not sure how performance compares with the MS article's way of doing this, but if you're using access I suspect you have other things to worry about ;).
SQL Fiddle: http://sqlfiddle.com/#!6/6f93b/2 (For SQL Server since Access not available, but I've tried to make it as similar as possible)
Create an union of all the ids from all tables, this way you get the id column in table4. Then encapsulate this union in a subselect (ids) and create left joins between this subselect (the parent join) and table1, table2, table3 (the childs join). Then select what you need...
Here is a variation on JohnLBevan's answer that will work if [Value1], [Value2], and [Value3] are of different types. For example, with
Table1
Table2
Table3
the query
returns
Explanation:
The first piece of the UNION subquery creates a single row with dummy values to ensure that the result of the UNIONs has the correct column types
returns
The rest of the UNION subquery appends the actual rows from each table
giving us
The outer aggregation query excludes the first row with the dummy values (WHERE ID > 0), gives us one row per ID (GROUP BY ID), and uses the MAX() function to return a value if there is one (or Null if there isn't).