OK, a slight variation on an earlier theme. Using the same basic idea, I want to get independent counts of the fields, then I want them grouped by a higher order breakdown.
I expanded the example by David to include a higher order column:
district_id, product_id, service_id
dist proj serv
1 1 1
1 1 2
1 1 2
1 1 3
1 1 3
1 1 4
1 2 2
1 2 4
1 2 4
1 2 5
1 2 5
2 1 1
2 2 1
2 1 6
2 2 6
2 3 6
To get a result on the total, I used a simple query with two sub-queries.
select
(select count(Distinct project_id) from GroupAndCountTest) AS "projects",
(select count(Distinct service_id) from GroupAndCountTest) as "services";
projects services
3 6
The challenge was to get this grouped within the district_id. What I wanted was:
district_id projects services
1 2 5
2 3 6
I ended up using similar sub-queries, but the only way I was able to combine them (other than using a stored function) was to re-run the sub-queries for every district. (Not a big problem here, but in my application the sub-queries use multiple tables with a substantial number of “districts” so the two sub-queries are run again for each “district” which will become increasingly ineffecient.
This query works, but I would love to see something more effecient.
select t1.district_id, p1.projects, s1.services
from GroupAndCountTest as t1
join (select district_id, count(Distinct project_id) as projects
from GroupAndCountTest
group by district_id) AS p1
on p1.district_id=t1.district_id
join (select district_id, count(Distinct service_id) as services
from GroupAndCountTest
group by district_id) as s1
on s1.district_id=t1.district_id
group by t1.district_id;
Thanks.
PS: If you want to experiment, you can create the table with:
CREATE TABLE `GroupAndCountTest` (
`district_id` int(5) DEFAULT NULL,
`project_id` int(5) DEFAULT NULL,
`service_id` int(5) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
insert into `GroupAndCountTest`(`district_id`,`project_id`,`service_id`)
values (1,1,1),(1,1,2),(1,1,2),(1,1,3),(1,1,3),(1,1,4),(1,2,2),(1,2,4),
(1,2,4),(1,2,5),(1,2,5),(2,1,1),(2,2,1),(2,1,6),(2,2,6),(2,3,6);
where MyTable contains
district_id, product_id, service_idcolumns