質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

Q&A

解決済

3回答

2456閲覧

mysql 年齢を指定した範囲内をGROUP BYしたい

kiki-natume

総合スコア7

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

0グッド

1クリップ

投稿2018/02/14 16:51

mysqlにて下記のテーブルを使い下記のようなことが出来ないかわかるかたがいらしたら
よろしくお願い致します。

<したいこと>
テーブルの「birth」の値を年齢を取得して、
・17歳未満
・18〜24歳
・25〜34歳
・35〜44歳
・45〜54歳
・55〜64歳
・65歳以上
でGROUP BYしたいです。

#今まで使っていたsql 年齢計算のSQL (YEAR(create()) - YEAR(birth)) - (RIGHT(create(), 5) < RIGHT(birth, 5)) AS age from table; #サンプル +----------+------------+------------+ | name | birth | CURDATE() | +----------+------------+------------+ | 田中 | 1982-01-15 | 2018-02-15 | | 佐藤 | 1992-03-23 | 2018-02-15 | | 鈴木 | 1970-05-05 | 2018-02-15 | | 中川 | 1960-12-26 | 2018-02-15 | | 安田 | 1920-05-21 | 2018-02-15 | | 高橋 | 1958-08-11 | 2018-02-15 | | 木村 | 1976-12-31 | 2018-02-15 | | 加賀 | 1988-02-16 | 2018-02-15 | | 安井 | 2000-01-30 | 2018-02-15 | +----------+------------+------------+

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

今MySQLの環境がないのでこんな感じということで願います。

SQL

1SELECT 2 CASE age_range 3 WHEN 1 THEN '17歳未満' 4 WHEN 2 THEN '18〜24歳' 5 WHEN 3 THEN '25〜34歳' 6 WHEN 4 THEN '35〜44歳' 7 WHEN 5 THEN '45〜54歳' 8 WHEN 6 THEN '55〜64歳' 9 ELSE '65歳以上' 10 END AS age_range 11 , COUNT(*) 12FROM( 13 SELECT 14 CASE 15 WHEN age < 18 THEN 1 16 WHEN age < 25 THEN 2 17 WHEN age < 35 THEN 3 18 WHEN age < 45 THEN 4 19 WHEN age < 55 THEN 5 20 WHEN age < 65 THEN 6 21 ELSE 7 22 END AS age_range 23 FROM( 24 SELECT 25 (YEAR(create()) - YEAR(birth)) - (RIGHT(create(), 5) < RIGHT(birth, 5)) AS age 26 from table 27 ) 28 ) 29GROUP BY age_range 30ORDER BY age_range

投稿2018/02/14 21:47

編集2018/02/14 22:53
Orlofsky

総合スコア16415

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

(たとえばテンポラリで)年齢グループテーブルをつくりbirthdayを
その範囲に当てはめるほうがSQLらしいと思います

  • ユーザーテーブル

SQL

1create table user(id int,name varchar(20),birth date); 2insert into user values 3(1,'taro','2010-01-01'), 4(2,'jiro','2001-02-15'), 5(3,'saburo','2001-12-31'), 6(4,'hanako','1990-01-01');
  • 年齢テーブルをつくってjoin

SQL

1create temporary table nenrei_group (id int,val varchar(20),start date,end date); 2insert into nenrei_group values 3(1,'17歳未満',current_date - interval 17 year + interval 1 day,current_date), 4(2,'17-24歳',current_date - interval 24 year + interval 1 day,current_date - interval 17 year), 5(3,'25-34歳',current_date - interval 34 year + interval 1 day,current_date - interval 24 year); 6select name,val from user as t1 7inner join nenrei_group as t2 8on t1.birth between t2.start and t2.end; 9
  • 集計

SQL

1create temporary table nenrei_group (id int,val varchar(20),start date,end date); 2insert into nenrei_group values 3(1,'17歳未満',current_date - interval 17 year + interval 1 day,current_date), 4(2,'17-24歳',current_date - interval 24 year + interval 1 day,current_date - interval 17 year), 5(3,'25-34歳',current_date - interval 34 year + interval 1 day,current_date - interval 24 year); 6 7select t2.id,val,count(*) as cnt from user as t1 8inner join nenrei_group as t2 9on t1.birth between t2.start and t2.end 10group by t2.id,val 11order by t2.id;

nenrei_groupテーブルはテンポラリではなく、普通にテーブルをつくっておいて
日が変わるごとに1度更新をかけるだけでもOKです

投稿2018/02/15 01:38

yambejp

総合スコア114585

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

MySQL 5.6 にて、以下のクエリで動作を確認しました。
(※テーブル名は、q113552 としています。)

sql

1SELECT 2 age_range AS '年齢区分' , 3 COUNT(*) AS '人数' 4FROM ( 5 SELECT 6 name, birth, 7 (@age:=FLOOR(DATEDIFF(NOW(), birth) / 365.25)) AS age, 8 ( 9 CASE 10 WHEN @age < 18 THEN '18歳未満' 11 WHEN @age < 35 THEN '18歳以上 34歳以下' 12 WHEN @age < 45 THEN '35歳以上 44歳以下' 13 WHEN @age < 55 THEN '45歳以上 54歳以下' 14 WHEN @age < 65 THEN '55歳以上 64歳以下' 15 ELSE '65歳以上' 16 END ) AS age_range 17 FROM q113552 18) table_with_age_range 19GROUP BY age_range 20ORDER BY age_range;

  
年齢を算出する

sql

1FLOOR(DATEDIFF(NOW(), birth) / 365.25))

は、stackoverflowの以下の投稿

how-to-calculate-age-in-years-based-on-date-of-birth-and-getdate

の回答に出ていた、シンプルなコード

I have used this query in our production code for nearly 10 years: SELECT FLOOR((CAST (GetDate() AS INTEGER) - CAST(Date_of_birth AS INTEGER)) / 365.25) AS Age J__ answered Oct 15 '09 at 13:07

の算出方法を("in our production code for nearly 10 years"と言っているのを信じて)使いました。
ただし、この回答のコメントにあるように、少し不正確なところがあります。

また、年齢の区分によって GROUP BY するのは、同じくstackoverflowの

sql-group-by-age-range

を参考にしました。

以下は動作確認のログです。

[ykt68@macbook15 ~]$ mysql -u root -p teratail_db Enter password: Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 1160 Server version: 5.6.38 MySQL Community Server (GPL) Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> SELECT name, birth FROM q113552; +--------+------------+ | name | birth | +--------+------------+ | 田中 | 1982-01-15 | | 佐藤 | 1992-03-23 | | 鈴木 | 1970-05-05 | | 中川 | 1960-12-26 | | 安田 | 1920-05-21 | | 高橋 | 1958-08-11 | | 木村 | 1976-12-31 | | 加賀 | 1988-02-16 | | 安井 | 2000-01-30 | +--------+------------+ 9 rows in set (0.00 sec) mysql> SELECT -> age_range AS '年齢区分' , -> COUNT(*) AS '人数' -> FROM ( -> SELECT -> name, birth, -> (@age:=FLOOR(DATEDIFF(NOW(), birth) / 365.25)) AS age, -> ( -> CASE -> WHEN @age < 18 THEN '18歳未満' -> WHEN @age < 35 THEN '18歳以上 34歳以下' -> WHEN @age < 45 THEN '35歳以上 44歳以下' -> WHEN @age < 55 THEN '45歳以上 54歳以下' -> WHEN @age < 65 THEN '55歳以上 64歳以下' -> ELSE '65歳以上' -> END ) AS age_range -> FROM q113552 -> ) table_with_age_range -> GROUP BY age_range -> ORDER BY age_range; +-------------------------+--------+ | 年齢区分 | 人数 | +-------------------------+--------+ | 18歳以上 34歳以下 | 3 | | 35歳以上 44歳以下 | 2 | | 45歳以上 54歳以下 | 1 | | 55歳以上 64歳以下 | 2 | | 65歳以上 | 1 | +-------------------------+--------+ 5 rows in set (0.00 sec) mysql>

補足

ご質問に挙がっていた、

年齢計算のSQL
(YEAR(create()) - YEAR(birth)) - (RIGHT(create(), 5) < RIGHT(birth, 5)) AS age from table;

を、そのまま使うと以下のようにエラーになりました。質問者様のお使いの MySQL と、私の使っている MySQL とのバージョン違いの問題でしょうか?

mysql> SELECT name, birth, (YEAR(create()) - YEAR(birth)) - (RIGHT(create(), 5) < RIGHT(birth, 5)) AS age FROM q113552; ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'create()) - YEAR(birth)) - (RIGHT(create(), 5) < RIGHT(birth, 5)) AS age FROM q1' at line 1

投稿2018/02/14 22:19

編集2018/02/15 21:25
jun68ykt

総合スコア9058

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2018/02/14 23:05

DATEDIFFの第三引数にyearやmonthを設定するのはずれすぎるんだっけ?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問