OK、以前のテーマのわずかなバリエーション。同じ基本的な考え方を使用して、フィールドの独立したカウントを取得し、それらをより高次の内訳でグループ化したいと考えています。
David の例を拡張して、高次の列を含めました。
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
合計の結果を得るために、2 つのサブクエリを持つ単純なクエリを使用しました。
select
(select count(Distinct project_id) from GroupAndCountTest) AS "projects",
(select count(Distinct service_id) from GroupAndCountTest) as "services";
projects services
3 6
課題は、これを district_id 内でグループ化することでした。私が欲しかったのは:
district_id projects services
1 2 5
2 3 6
同様のサブクエリを使用することになりましたが、(ストアド関数を使用する以外に) それらを組み合わせることができた唯一の方法は、地区ごとにサブクエリを再実行することでした。(ここでは大きな問題ではありませんが、私のアプリケーションでは、サブクエリはかなりの数の「地区」を持つ複数のテーブルを使用するため、「地区」ごとに 2 つのサブクエリが再度実行され、ますます非効率的になります。
このクエリは機能しますが、もっと効率的なものを見たいと思っています。
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;
ありがとう。
PS: 実験したい場合は、次を使用してテーブルを作成できます。
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);