Mysqlには、id、birth_year、および性別の患者テーブルがあります。次のテーブルは、id、patient_id [患者からのFK]、checkup_dateを持つトランザクションです。年齢の範囲内のすべての男性と女性の健康診断の数が得られるように、行を選択する必要があります。
次の表形式の結果を達成するためにクエリを実行するにはどうすればよいですか?
20歳未満:男性:10回、女性:15回
21〜30、男性:20回、女性:35回
31〜40、男性:30回、女性:45回
.... ....... ......... ....... ........ ..........
81〜90、男性:10回、女性:6回
90歳以上、男性:0回、女性:4回
ありがとうございました。
2つのオプション。
a)サブクエリを使用する
select
concat(10*floor(age/10), '-', 10*floor(age/10) + 10) as `range`,
gender,
count(*) as count
from (
select
*,
TIMESTAMPDIFF(YEAR,birth_year,CURDATE()) AS age
from
transaction left join patient on patient_id = patient.id
) as t group by `range`, gender;
与える
+-------+--------+-------+
| range | gender | count |
+-------+--------+-------+
| 0-10 | m | 2 |
| 10-20 | m | 1 |
| 20-30 | m | 3 |
| 30-40 | f | 2 |
| 30-40 | m | 2 |
| 50-60 | f | 1 |
| 50-60 | m | 1 |
| 60-70 | f | 5 |
| 60-70 | m | 3 |
| 70-80 | f | 1 |
| 70-80 | m | 6 |
+-------+--------+-------+
b)最初に年齢でグループ化し、次に適用範囲内でグループ化します。
ORMを使用する場合、サブクエリを実行するのは簡単ではないので、これは良いアイデアかもしれません。
パフォーマンスの観点:平均的な人間が100年間住んでいることを考えると、アプリケーションで簡単にループできる最大200のレコード(男性100と女性100)が存在する可能性があります。
select
gender,
TIMESTAMPDIFF(YEAR,birth_year,CURDATE()) AS age,
count(*)
from
transaction left join patient on patient_id = patient.id
group by age, gender
与える
+--------+------+----------+
| gender | age | count(*) |
+--------+------+----------+
| m | 4 | 2 |
| m | 14 | 1 |
| m | 24 | 3 |
| f | 34 | 2 |
| m | 34 | 2 |
| f | 54 | 1 |
| m | 54 | 1 |
| f | 64 | 5 |
| m | 64 | 3 |
| f | 74 | 1 |
| m | 74 | 6 |
+--------+------+----------+