🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
MySQL

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

Q&A

解決済

5回答

1417閲覧

MySQLでグループ化した上で、特定カラムの値が同じかどうかを判定したい

qwe001

総合スコア133

MySQL

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

0グッド

4クリップ

投稿2019/09/26 10:00

編集2019/09/26 10:01

次のようなテーブルがあります

SELECT id, alive, open_at FROM schedules; +----+-------+---------------------+ | id | alive | open_at | +----+-------+---------------------+ | 1 | 1 | 2019-11-01 00:00:00 | | 2 | 0 | 2019-11-30 00:00:00 | | 3 | 1 | 2019-12-01 00:00:00 | | 4 | 1 | 2019-12-31 00:00:00 | | 5 | 0 | 2020-01-01 00:00:00 | | 5 | 0 | 2020-01-31 00:00:00 | +----+-------+---------------------+

これらを年別にグループ化すると次のようになります

SELECT DATE_FORMAT(open_at, '%Y') AS op_year, DATE_FORMAT(open_at, '%c') AS op_month FROM schedules GROUP BY (DATE_FORMAT(open_at, '%Y-%m')) HAVING op_year = 2019 ; +---------+----------+ | op_year | op_month | +---------+----------+ | 2019 | 11 | | 2019 | 12 | | 2020 | 1 | +---------+----------+

今回したいことは、年別にグループ化した上で、
そのグループにあるレコードのaliveの値が、全て1であるか否かを取得することです。

次のような形でレコードを取得したいです

SELECT (なにかCASE文を使う?) AS alives, DATE_FORMAT(open_at, '%Y') AS op_year, DATE_FORMAT(open_at, '%c') AS op_month FROM schedules GROUP BY (DATE_FORMAT(open_at, '%Y-%m')) HAVING op_year = 2019 ; +--------+---------+----------+ | alives | op_year | op_month | +--------+---------+----------+ | 0 | 2019 | 11 | | 1 | 2019 | 12 | | 0 | 2020 | 1 | +--------+---------+----------+

このような形でレコードを取得するには、どのようなSQL文を発行すればいいのでしょうか?

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

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

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

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

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

guest

回答5

0

aliveが数値で0と1という前提で、以下でどうでしょう。

SQL

1SELECT 2 case when sum(alive)=count(*) then 1 else 0 end AS alives, 3 DATE_FORMAT(open_at, '%Y') AS op_year, 4 DATE_FORMAT(open_at, '%c') AS op_month 5FROM schedules 6 GROUP BY (DATE_FORMAT(open_at, '%Y-%m'))

投稿2019/09/27 05:59

sazi

総合スコア25327

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

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

0

ベストアンサー

「なにかCASE文を使う?」
⇒この形が分かりやすくて良いと思います。

「全て1であるか否かを取得する」であれば、
kasa0様の内容([s]の有無の違いはあります)、
Kosuke_Shibuya様の内容(case文で実現する場合でもヒントになるかと思います)で良いかと思います。

また、少し変えて、以下の内容でも大丈夫です。

SQL

1( 2 CASE 3 WHEN max( alive ) = 1 AND COUNT( distinct alive ) = 1 THEN max( alive ) 4 ELSE 0 5 END 6) as alives

以下、他の方法のおまけ回答です。

「特定カラムの値が全て同じかどうか」という場合、
max(alives)=min(alives) に違和感があるのであれば、
以下のような方法もあります。

SQL

1( 2 CASE 3 WHEN COUNT('X') = SUM( CASE WHEN alive = 1 THEN 1 ELSE 0 END ) THEN 1 4 ELSE 0 5 END 6) as alives

投稿2019/09/26 11:44

tomari_perform

総合スコア760

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

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

qwe001

2019/09/27 08:18

丁寧なご回答誠にありがとうございます。こちらのやり方で期待した通りにできました。
guest

0

sql

1SELECT 2 COUNT(distinct `alive`) = 1 and MAX(distinct `alive`) = 1 and MIN(distinct `alive`) = 1 as alive, 3 -- COUNT(distinct `alive`), 4 -- MAX(distinct `alive`), 5 -- MIN(distinct `alive`), 6 YEAR(open_at) AS op_year, 7 MONTH(open_at) AS op_month 8FROM schedules 9 GROUP BY (DATE_FORMAT(open_at, '%Y-%m')) 10 HAVING op_year = 2019

投稿2019/09/26 11:12

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

0

良い方法が思いつかなかった。

SQL

1CASE WHEN max(alives)=min(alives) THEN max(alives) 2ELSE 0 3END AS alives

投稿2019/09/26 10:34

kasa0

総合スコア578

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

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

0

SQL

1SELECT 2 MAX(alives) AS alives, 3 DATE_FORMAT(open_at, '%Y') AS op_year, 4 DATE_FORMAT(open_at, '%c') AS op_month 5FROM schedules 6 GROUP BY (DATE_FORMAT(open_at, '%Y-%m')) 7-- HAVING op_year = 2019 8WHERE alives = 1;

では駄目でしょうか?

投稿2019/09/26 10:16

nandymak

総合スコア799

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

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

nandymak

2019/09/26 10:34 編集

alives=0の行も必要ですかね。 alivesの合計を件数で割って、小数点以下は切り捨てればいけるかも。 その時はWHERE alives = 1は不要です。 TRUNCATE(SUM(alives)/COUNT(alives),0) 平均をTRUNCATEでも良いかも。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問