When you join 2 tables that have a one to many relationship, the data in the table on the one-side gets repeated for evry matching row on the many side
one_table
one_id
1
2
3
4
5
many_table
many_id | one_id
1 | 1
2 | 1
3 | 2
4 | 3
5 | 2
6 | 3
Joined would give
one_table.one_id | many_table.one_id | many_table.many_id
1 | 1 | 1
1 | 1 | 2
2 | 2 | 3
2 | 2 | 5
3 | 3 | 4
3 | 3 | 6
When you then join that to a third table, the multiple instances of one_table.one_id ALL get joined to the third table; and it gets worse if there is a one to many relationship with the third table as that will also multiply the instances of one_id, which in turn will multiply the instances of many_id. Hence your multiplication of results.
1id | 1id | mid | 3id
1 | 1 | 1 | 56
1 | 1 | 1 | 57
1 | 1 | 2 | 58
2 | 2 | 3 | 59
2 | 2 | 3 | 60
2 | 2 | 5 | 70
2 | 2 | 5 | 75
etc
The way around this is to use a sub-query to get the aggregate results from the first 2 tables, and then join the third table to that. Your version must support sub-queries for this to work
(I'm just going to show you how cos I can't be doing with typing all your column names etc)
$query = "SELECT t3.col1, t1.col2, t1.tots FROM table3 as t3 INNER JOIN
(SELECT a.col2 AS col2, count(b.col1) AS tots FROM table1 AS a INNER JOIN table2 as b
GROUP BY a.col2 ORDER BY a.col2) AS t1"
The sub-query in the FROM clause returns a table-type recordset which MUST be aliased with a table name. You can then just join to it like any other table.
This is, as I said, about the only way to do aggregate results with more than 2 tables.