简体   繁体   中英

MySQL join and COUNT() on multiple tables

I'm trying to COUNT() on multiple tables in one query, but I can't get it to work. Here's what I have so far:

TABLES:

table1
---------------------
id | name
---------------------
 1 | test
 2 | test2


table2
---------------------
id | table1_id
---------------------
 1 | 1
 2 | 1
 3 | 1


table3
---------------------
id | table2_id
---------------------
 1 | 1


table4
---------------------
id | size | table3_id
---------------------
 1 | 1024 | 1
 1 | 200  | 1

SQL:

SELECT
    table1.name,
    COUNT(table2.table1_id) AS table2_count,
    COUNT(table3.table2_id) AS table3_count,
    COUNT(table4.table3_id) AS table4_count,
    SUM(table4.size) AS table4_size
FROM
    table1
LEFT JOIN table2
    ON table1.id = table2.table1_id
LEFT JOIN table3
    ON table2.id = table3.table2_id
LEFT JOIN table4
    ON table3.id = table4.table3_id
WHERE
    table1.id = 1

Results I'm getting from the above query:

name | table2_count | table3_count | table4_count | table4_size
---------------------------------------------------------------
test |      4       |      2       |      2       |    1224

Results that I should be getting:

name | table2_count | table3_count | table4_count | table4_size
---------------------------------------------------------------
test |      3       |      1       |      2       |    1224

You will need to use DISTINCT , but also you need to count the IDs, not the foreign keys:

SELECT
    table1.name,
    COUNT(DISTINCT table2.id) AS table2_count,
    COUNT(DISTINCT table3.id) AS table3_count,
    COUNT(DISTINCT table4.id) AS table4_count,
    SUM(table4.size) AS table4_size
FROM table1
LEFT JOIN table2 ON table1.id = table2.table1_id
LEFT JOIN table3 ON table2.id = table3.table2_id
LEFT JOIN table4 ON table3.id = table4.table3_id
WHERE table1.id = 1

Here is a fiddle .

Explanation: The DISTINCT key word eliminates all duplicate values resulting in a list of unique values.

If you run your query without the COUNT() and SUM() , you get:

name  table1_id  table2_id  table3_id  size
test  1          1          1          1024 
test  1          1          1          200 
test  1          (null)     (null)     (null) 
test  1          (null)     (null)     (null)

So if you add the COUNT() and SUM() , you obviously get:

name  table1_id  table2_id  table3_id  size
test  4          2          2          1224

However, using DISTINCT with your query won't help because you can clearly see the duplicate values, which will result in:

name  table1_id  table2_id  table3_id  size
test  1          1          1          1224

Now, if you run my query without the COUNT() and SUM() , you get:

name  table1_id  table2_id  table3_id  size
test  1          1          1          1024 
test  1          1          2          200 
test  2          (null)     (null)     (null) 
test  3          (null)     (null)     (null)

If you add the COUNT() and SUM() , you get exactly the same results like your query:

name  table1_id  table2_id  table3_id  size
test  4          2          2          1224

However, because this time you have different values (ie not all are 1), so now if you count the unique values using DISTINCT , you get:

name  table1_id  table2_id  table3_id  size
test  3          1          2          1224

Can you try this way

SELECT  table1.name,
    (SELECT COUNT(table2.table1_id) WHERE  table1.id = table2.table1_id ) AS table2_count,
    (SELECT COUNT(table3.table2_id) WHERE  table2.id = table3.table1_id ) AS table3_count,
    (SELECT COUNT(table4.table3_id) WHERE  table3.id = table4.table1_id ) AS table4_count,
    (SELECT SUM(table4.size) WHERE  table3.id = table4.table1_id ) AS table4_size
    FROM
    table1
    WHERE
    table1.id = 1

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM