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

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

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

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Q&A

解決済

1回答

24459閲覧

絞り込んだデータを結合してさらに絞り込む場合のSQLについて

qopllqopllqop

総合スコア36

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

0グッド

0クリップ

投稿2016/05/13 23:10

編集2016/05/14 20:37

###実現したいこと
t_conversionのデータを一旦ユーザーIDで絞り込み、作成した1日〜31日までの日付テーブルにLEFT JOINし、結合したデータを期間をさらに指定して絞り込みたいと考えています。

1つのSQLで実行しようとするとき、ユーザーIDの絞り込みと期間の絞り込みが2回発生しますが、WHERE句をどのように書けば良いのかわかりません。
VIEWを使って、あらかじめユーザーIDを絞り込んだテーブルを作ってからLEFT JOINさせる方が良いのでしょうか?
もしくは1つのSQL内でWHERE句を上手に書く書く方法はあるのでしょうか?

どちらの方向が良いのかご教授いただければ幸いです。
よろしくお願いいたします。

###該当のソースコード
vw_sequence99
+-------+
| Number |
+-------+
0
1
2
3
4
~
99

t_conversion
+-------+-----------------+
|user_id| conversion_date |
+-------+-----------------+
|001 |2016-05-01
|002 |2016-05-01
|002 |2016-05-03
~
|001 |2016-05-31

SQL

1SELECT ADDDATE('2016-05-01',V.Number ) AS DATE, IFNULL(COUNT(C.conversion_date),0) AS conversion 2FROM vw_sequence99 AS V 3LEFT JOIN t_conversion AS C 4ON ADDDATE('2016-05-01',V.Number ) = DATE(C.conversion_date) 5WHERE ADDDATE('2016-05-01',V.Number) BETWEEN '2016-05-01' AND '2016-05-31' 6GROUP BY ADDDATE('2016-05-01',V.Number)

###試したこと
IFNULL(SELECT COUNT(C.conversion_date) FROM t_conversion WHERE user_id = 001),0)
としてみましたが、上手くいきませんでした。

VIEWの作成

SQL

1DROP VIEW vw_conversion; 2CREATE VIEW vw_conversion AS 3SELECT conversion_date 4FROM t_conversion 5WHERE user_id = 001; 6SELECT ADDDATE( '2016-05-01', V.Number ) AS DATE, IFNULL( COUNT( C.conversion_date ) , 0 ) AS conversion 7FROM vw_sequence99 AS V 8LEFT JOIN vw_conversion AS C 9ON ADDDATE( '2016-05-01', V.Number ) = DATE( C.conversion_date ) 10WHERE ADDDATE('2016-05-01', V.Number) BETWEEN '2016-05-01' AND '2016-05-31' 11GROUP BY ADDDATE('2016-05-01', V.Number)

とすれば期待通りの結果が得られるのですが、viewを使用すべきなのか、WHERE句で同じことができるのか
?疑問です。

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

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

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

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

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

yodel

2016/05/14 15:46

利用するテーブルとそのカラム、 取得したい期待表示結果がよく分かりませんでした…。
qopllqopllqop

2016/05/14 19:44

user_idが抜けていました。大変申し訳ありません! 利用するテーブルとカラムは vw_sequence99のNumber t_conversionのuser_idとconversion_dateです。 t_conversionをまず、user_idで絞り込み、2016-5-1〜2016-5-31の期間のconversion_dateのデータ数を日別に集計したいと考えています。ただし、conversion_dateが無い日付は0を表示させたいです。
guest

回答1

0

ベストアンサー

SQL Server でしょうか。
使ったことないんで間違ってたらご容赦願います。(^_^;
自分だったらこんな感じかなあ。

SQL

1SELECT V.Basedate, IFNULL(C.Convnum,0) AS Conversion 2FROM 3 (SELECT ADDDATE('2016-05-01',Number ) AS Basedate 4 FROM vw_sequence99) AS V 5LEFT JOIN 6 (SELECT DATE(conversion_date) AS Convdate, COUNT(*) AS Convnum 7 FROM t_conversion 8 WHERE user_id = '001' 9 GROUP BY DATE(conversion_date)) AS C 10ON V.Basedate = C.Convdate 11WHERE V.Basedate BETWEEN '2016-05-01' AND '2016-05-31'

投稿2016/05/14 20:54

編集2016/05/14 21:06
takasima20

総合スコア7458

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

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

qopllqopllqop

2016/05/14 21:11

ご回答いただき、ありがとうございます! ご教示いただいたソースをヒントに無事解決することができました。 LEFT JOINするテーブルを指定するFROM句で括弧をつけてSELECT文を書けばよかったのですね。ありがとうございます!まだまだSQLの基礎がなっておらず、お手数をおかけいたしました! ```SQL SELECT ADDDATE( '2016-05-01', V.Number ) AS DATE, IFNULL( COUNT( C.conversion_date ) , 0 ) AS conversion FROM vw_sequence99 AS V LEFT JOIN (SELECT conversion_date FROM t_conversion WHERE user_id = 001) AS C ON ADDDATE( '2016-05-01', V.Number ) = DATE( C.conversion_date ) WHERE ADDDATE('2016-05-01', V.Number) BETWEEN '2016-05-01' AND '2016-05-31' GROUP BY ADDDATE('2016-05-01', V.Number) ```
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問