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

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

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

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

Q&A

解決済

2回答

251閲覧

列ごとに日付を持ち、ある条件を満たす日付のみ取得したい。

fjaiofjawiefjaw

総合スコア210

MySQL

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

0グッド

0クリップ

投稿2018/08/18 21:10

編集2018/08/18 21:19

下記の様に、テーブルとデータを作成します。

sql

1CREATE TABLE `sample_table` ( 2 `id` int NOT NULL AUTO_INCREMENT PRIMARY KEY, 3 `date` date NOT NULL, 4 `number` int(11) NOT NULL 5); 6 7INSERT INTO `sample_table` (`date`, `number`) 8VALUES ('2018-08-01', '1'); 9INSERT INTO `sample_table` (`date`, `number`) 10VALUES ('2018-08-01', '2'); 11INSERT INTO `sample_table` (`date`, `number`) 12VALUES ('2018-08-01', '3'); 13INSERT INTO `sample_table` (`date`, `number`) 14VALUES ('2018-08-02', '1'); 15INSERT INTO `sample_table` (`date`, `number`) 16VALUES ('2018-08-02', '2'); 17INSERT INTO `sample_table` (`date`, `number`) 18VALUES ('2018-08-03', '1'); 19INSERT INTO `sample_table` (`date`, `number`) 20VALUES ('2018-08-03', '3'); 21INSERT INTO `sample_table` (`date`, `number`)

dateカラムとnumberカラムの対応を見た場合、
2018-08-01は、numberカラムの値、1,2,3を全て持ちます。
しかし、
2018-08-02は、1,2のみ
2018-08-03は、1,3のみ
つまり、全てを持っていません。

この全てを持っていない
2018-08-02と2018-08-03
を表示することは、可能でしょうか。
可能な場合、
どのような構文を利用すればいいのでしょうか?
※そもそも、table構造的に無理なのかもしれないと思っております。

自身で書いたsql文(申し訳ありません、自身では、まったく思いつきませんでした。)

sql

1SELECT date 2FROM sample_table 3WHERE date between '2018-08-01' AND '2018-08-31' 4GROUP BY date

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

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

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

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

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

guest

回答2

0

date別のnumberの要素数と全体での要素数を比較します。

SQL

1select date FROM sample_table group by date 2having count(distinct number) !=(select count(distinct number) from sample_table)

全体の要素数が予め決まっているなら以下のように記述できます。

SQL

1select date FROM sample_table group by date 2having count(distinct number) !=3

投稿2018/08/18 21:29

編集2018/08/18 22:11
sazi

総合スコア25138

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

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

fjaiofjawiefjaw

2018/08/18 21:46

ご回答ありがとうございます。 countがなぜ、集約関数と呼ばれているか、少しは理解できた気がします。 しかし、グループ化のイメージがまだよく頭の中で出来ていないので、完璧には理解できませんでした。 sql文のグループ化を利用する中で、勉強していきたいと思います。
sazi

2018/08/18 22:11

説明的に追記しました。
fjaiofjawiefjaw

2018/08/19 08:36 編集

追記の方、確認させて頂きました。 ありがとうございます。 以下、自分なりの解釈です。 あるカラムをグループ化することにより、同一の特徴を持ったもの同士の各グループに分けることができる。 名称が正しいか不明ですが、グループ関数(countやdistinct)?は、上記で作られた各グループに対して実行される。 distinctでnumberカラムの重複を排除し、それをcountでカウントする。 ご回答頂いた、2個目のsqlの要素数とは、今回のnumberカラムの数を表しており、1と2と3の3個ということですね。 大変、勉強になるsqlでした。 ありがとうございました。
guest

0

ベストアンサー

sql

1SELECT `date` FROM sample_table 2WHERE `date` NOT IN ( 3 SELECT `date` FROM sample_table 4 GROUP BY `date` 5 HAVING count(DISTINCT `number`) = 3 6) 7GROUP BY `date`

投稿2018/08/18 21:18

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

fjaiofjawiefjaw

2018/08/19 17:42 編集

ご回答ありがとうございます。 非常に早い回答、誠にありがとうございます。 sqlの一つ一つの構文は、サラッと見た程度で分かった気になっておりましたが、 回答のようなテクニカルなsql文(しかもこの短時間で)は、見たことがありませんでした。 もう少し、勉強、頑張りたいと思います。ありがとうございました。 追記(2018/08/20/02:38) 自身の今後の勉強のために 見返すかもしれませんので、長文失礼いたします。 以下、自身の解釈です。 まず、サブクエリ内で dateをグループ化する。 その各dateグループに対して、 numberカラムの重複を削除した個数をカウントする。 ※1と2と3、全てある場合は、3個。 having句により、個数が、3個の場合のグループを抽出する。 つまり、サブクエリで得られるものは、 1と2と3を全て含むdate値ということ。 メインクエリ内では、 where句により サブクエリから得た 1と2と3を全て含むdate値群のどれとも合致しない つまり、 1 AND 2 AND 3 の逆は、 1でない OR 2でない OR 3でない なので、 1と2と3の内、(0個)or1個or2個を含む date値を取得。 ※0個の場合が存在することは、ベン図をイメージしたら 分かりました。 しかし、0個は、numberカラムの値を外部キーなどで1,2,3に縛る。 かつ、nullを禁止すれば無くせるため、 今回は、1個or2個として機能する。 sazi様との回答の違いとしては、 sazi様のsql文は、メインクエリ内で、ダイレクトに求めるもので 今回の場合は、サブクエリで逆の条件のものを求め、それの否定を得るものであると認識させて頂きました。 大変勉強になりました。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問