[nycphp-talk] MySQL: count()children on 2 related tables in 1 query
Dan Cech
dcech at phpwerx.net
Tue Jan 4 16:50:48 EST 2011
Rob,
On 1/4/2011 4:28 PM, Rob Marscher wrote:
> insert into parent (name) values ('One'),('Two'),('Three');
> insert into child1 (parent_id) values (1),(1),(1),(3);
> insert into child2 (parent_id) values (2),(2),(2),(3);
>
> explain select parent.id, parent.name, count(child1.id), count(child2.id)
> from parent force index (primary)
> left join child1 on parent.id = child1.parent_id
> left join child2 on parent.id = child2.parent_id
> group by parent.id;
>
> +----+-------------+--------+-------+---------------+---------+---------+--------------------------+------+-------+
> | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
> +----+-------------+--------+-------+---------------+---------+---------+--------------------------+------+-------+
> | 1 | SIMPLE | parent | index | NULL | PRIMARY | 4 | NULL | 1 | |
> | 1 | SIMPLE | child1 | ref | parent | parent | 4 | brightbu_namco.parent.id | 2 | |
> | 1 | SIMPLE | child2 | ref | parent | parent | 4 | brightbu_namco.parent.id | 2 | |
> +----+-------------+--------+-------+---------------+---------+---------+--------------------------+------+-------+
> +----+-------+------------------+------------------+
> | id | name | count(child1.id) | count(child2.id) |
> +----+-------+------------------+------------------+
> | 1 | One | 3 | 0 |
> | 2 | Two | 0 | 3 |
> | 3 | Three | 1 | 1 |
> +----+-------+------------------+------------------+
This is demonstrating 2 special cases which will work properly:
1. no rows for a parent in one of the child tables
2. 1 row for a parent in both child tables
If you run your child inserts again to create more rows you'll end up
with a count of 4 instead of 2 in the 3rd row.
If you remove the count()s you can see why this is the case:
SELECT parent.id, parent.name, child1.id, child2.id
FROM parent FORCE INDEX (PRIMARY )
LEFT JOIN child1 ON parent.id = child1.parent_id
LEFT JOIN child2 ON parent.id = child2.parent_id;
+----+-------+------+------+
| id | name | id | id |
+----+-------+------+------+
| 1 | One | 1 | NULL |
| 1 | One | 2 | NULL |
| 1 | One | 3 | NULL |
| 1 | One | 5 | NULL |
| 1 | One | 6 | NULL |
| 1 | One | 7 | NULL |
| 2 | Two | NULL | 1 |
| 2 | Two | NULL | 2 |
| 2 | Two | NULL | 3 |
| 2 | Two | NULL | 5 |
| 2 | Two | NULL | 6 |
| 2 | Two | NULL | 7 |
| 3 | Three | 4 | 4 |
| 3 | Three | 4 | 8 |
| 3 | Three | 8 | 4 |
| 3 | Three | 8 | 8 |
+----+-------+------+------+
Dan
More information about the talk
mailing list