I have 3 tables:
A
B which has a foreign key to A
C same
How can I count the total number of relations that references a row in A?
ex.
A
+----+------+
| id | name |
+----+------+
| 1 | foo |
| 2 | bar |
+----+------+
B
+----+----+
| id | a |
+----+----+
| 1 | 1 |
| 2 | 1 |
| 3 | 2 |
| 4 | 2 |
+----+----+
C
+----+----+
| id | a |
+----+----+
| 1 | 1 |
| 2 | 1 |
+----+----+
I want to get this result:
+------+----+
| name | a |
+------+----+
| foo | 4 |
| bar | 2 |
+------+----+
Thanks
Edit 1: taking into account that all children tables may be empty
Edit 2: Accepted answer is inefficient and will result in temporary table being created by the union
of the size of B
+ C
, then grouping will be performed on that temporary table. An explain plan on that query reveals Using temporary; Using filesort
, both being bad:
+------+-------------+------------+-------+---------------+------+---------+-----------------+------+---------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+------------+-------+---------------+------+---------+-----------------+------+---------------------------------+
| 1 | PRIMARY | A | ALL | NULL | NULL | NULL | NULL | 5 | Using temporary; Using filesort |
| 1 | PRIMARY | <derived2> | ref | key0 | key0 | 5 | A.id | 2 | |
| 2 | DERIVED | B | index | NULL | a | 4 | NULL | 15 | Using index |
| 3 | UNION | C | index | NULL | a | 4 | NULL | 14 | Using index |
+------+-------------+------------+-------+---------------+------+---------+-----------------+------+---------------------------------+
While if you simply sum up the individual COUNT
, you would only have the indexes being queried to know the amount of elements:
SELECT name,
(SELECT COUNT(*) FROM B WHERE B.a = A.id) +
(SELECT COUNT(*) FROM C WHERE C.a = A.id) AS count
FROM A;
This would result in the following explain plan:
+------+--------------------+-------+------+---------------+------+---------+-----------------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+--------------------+-------+------+---------------+------+---------+-----------------+------+-------------+
| 1 | PRIMARY | A | ALL | NULL | NULL | NULL | NULL | 5 | |
| 3 | DEPENDENT SUBQUERY | C | ref | a | a | 4 | A.id | 1 | Using index |
| 2 | DEPENDENT SUBQUERY | B | ref | a | a | 4 | A.id | 1 | Using index |
+------+--------------------+-------+------+---------------+------+---------+-----------------+------+-------------+
Queries and explain plan of accepted answer + this one available in the demo.