I’m having an issue with MS Access to get correct counts on multiple tables. I’m not at all an expert in SQL requests.
I have a set of tables which is structured as follow :
- Table1 : UID, Name, other informations
- Table2 : UID, FK_UID_Table1, Name, other informations
- Table3 : UID, FK_UID_Table2, Name, other informations
- Table4 : UID, FK_UID_Table3, Name, other informations
Each FK reference is 1-N, with N >= 0. So it is possible that an item in Table2 has no reference in Table3 FK.
What I’m trying to achieve is to get the count of each items in one query.
For example, if I select an item in Table1 I would like to get :
Table1.Name | Count(Table2.UID) | Count(Table3.UID) | Count(Table4.UID)
I succeed to get the exact count with one INNER JOIN as follow :
SELECT g.UID, Table1.Name, COUNT(s.UID) AS CountTable2FROM Table1 AS g INNER JOIN Table2 AS s ON s.FK_Table1 = g.UIDGROUP BY g.UID, g.NameFor example, with an item in Table1 who gets 2 references in Table2, and 3 references in Table3, I get 2 as a result, which is correct.
When I try to add an other layer of counting, I did as follow :
SELECT g.UID, g.Name, COUNT(s.UID) AS CountTable2, COUNT(p.UID) AS CountTable3FROM (Table1 as gINNER JOIN Table2 AS s ON s.FK_Table1 = g.UID)INNER JOIN Table3 AS p ON p.FK_Table2 = s.UIDGROUP BY g.UID, g.Name, CountTable2, CountTable3With my previous example, instead of getting 2 for CountTable2 and 3 for CountTable3 as result, I get 3 and 3.
I read that this is an expected behaviour with Access, but I didn’t find how to make it works.
I was helped by this question : Inner join with count on three tables
Any help would be grately appreciated.
Advertisement
Answer
As I don’t succeed to get a result with Gordon Linoff answer, I tried an other way with LEFT OUTER JOIN.
Thanks to this post : How to get a group where the count is zero
I managed to get a correct result with void relations (for example, an item Table2 has no reference in Table3), but now I got an incorrect result when I join more than 2 tables.
I guess it’s a problem from my request…
Currently :
SELECT Table1.UID, Table1.NameCOUNT(Table2.UID) AS CountTable2FROM Table1LEFT OUTER JOIN Table2 ON Table2.FK_Table1 = Table1.UIDGROUP BY Table1.UID, Table1.Namegives me a correct result (only two tables related), but :
SELECT Table1.UID, Table1.NameCOUNT(Table2.UID) AS CountTable2, COUNT(Table3.UID) AS CountTable3FROM (Table1LEFT OUTER JOIN Table2 ON Table2.FK_Table1 = Table1.UID)LEFT OUTER JOIN Table3 ON Table3.FK_Table2 = Table2.UIDGROUP BY Table1.UID, Table1.Namegives me an incorrect result for CountTable2, which appears to be more than expected. CountTable3 is correct.
EDIT :
I finally figure how to make it works, according to my research and the hint from Gordon Linoff with aggregation before joining.
I start by counting the deepest table inside the table above, then join, and so on. At every step, I select the essentials informations to keep : UID, FK_AboveTable, Count, Sums from deepest table.
Final code :
SELECT Table1.UID, Table1.Name, COUNT(Table2.UID) AS TotalTable2, SUM(CountTable3) AS TotalTable3, SUM(CountTable4_2) AS TotalTable4FROM Table1 LEFT OUTER JOIN ( SELECT Table2.UID, Table2.FK_Table1, COUNT(Table3.UID) AS CountTable3, SUM(CountTable4) AS CountTable4_2 FROM Table2 LEFT OUTER JOIN ( SELECT Table3.UID, Table3.FK_Table1, COUNT(Table4.UID) AS CountTable4 FROM Port LEFT OUTER JOIN Table4 ON Table4.FK_Table3 = Table3.UID GROUP BY Table3.UID, Table3.FK_Table2 ) Table3 ON Table3.FK_Table2 = Table2.UID GROUP BY Table2.UID, Table2.FK_Table1 ) Table2 ON Table2.FK_Table1= Table1.UIDGROUP BY Table1.UID, Table1.Name ORDER BY Table1.Name DESCNote that void count from deepest table appears are void and no 0 (for example, if there is one item in Table1, none related in Table2, the count will be 0 for Table2, void for Table3 and Table4).
I assume this might be upgraded, but for now it solves my issue, and allows me to add as many tables as I need.