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

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

ただいまの
回答率

88.33%

SQLで行き詰まっています

解決済

回答 3

投稿

  • 評価
  • クリップ 1
  • VIEW 1,314
退会済みユーザー

退会済みユーザー

前任者からの引き継ぎが足らず、困っております。
SQLに不慣れなもので、どなたかご教示下さい。

4つのテーブルからなるデータベースからデータを抽出したいのですが、解決出来ずにおります。

テーブル構成は
1.通話履歴テーブル
CALL_ID(ユニーク)
顧客ID(=顧客テーブル.顧客ID)
アクション名
通話日時
対応優先度

2.顧客テーブル
顧客ID(ユニーク)
電話番号
住所
氏名
etc

3.電話番号履歴管理テーブル
登録日
電話番号
区分ID(=区分管理テーブル.区分ID)

4.区分管理テーブル
区分ID(ユニーク)
区分

という構成で、ここから、
顧客テーブル.電話番号, 通話履歴テーブル.アクション名, 通話履歴テーブル.対応優先度, 区分管理テーブル.区分

を一覧取得する必要があります。
これまでは単純にJOINするだけで実現出来ておりましたが、電話番号履歴管理テーブルに登録したデータに重複するケースがあり、条件をつけてデータを抽出しなければなりません。

例えば
2015/01/01にXという区分で09011112222という電話番号が登録されており、かつ、
2016/01/01にYという区分で09011112222という電話番号が登録されています

この時に2015/07/01に09011112222と通話した記録でデータを抽出するときに、 区分管理テーブル.区分はXで抽出しなければなりません。
つまり、通話した時点での区分を抽出したいのです。
このような組み合わせが多数あり、お手上げです。

抽出対象期間が2015/06/01~2016/01/01の通話履歴だとしたら、どのようなSQLなら、実現できますでしょうか?

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • ricy

    2016/06/02 19:21

    要件を理解しずらいため、エクセルにして、どのデータを抽出したいといった風に質問されると回答しやすいです。このサービスは添付不可だったらすみません・・・
    サブクエリをつかうか、動的なSQL(pl/sql等)を使えば実現できそうな気はしますが・・・・あと質問に関係のなさそうなカラムは記載なくてよいかと

    キャンセル

回答 3

checkベストアンサー

0

これでいかがでしょうか?

select
    サブクエリ.電話番号,
    サブクエリ.アクション名,
    サブクエリ.対応優先度,
    区分管理テーブル.区分
from
    区分管理テーブル,
    電話番号履歴管理テーブル,
    (
        select 
            顧客テーブル.電話番号,
            通話履歴テーブル.アクション名,
            通話履歴テーブル.対応優先度,
            max(電話番号履歴管理テーブル.登録日) 最新登録日
        from 
            通話履歴テーブル,
            顧客テーブル,
            電話番号履歴管理テーブル
        where 通話履歴テーブル.顧客ID = 顧客テーブル.顧客ID
        and   顧客テーブル.電話番号 = 電話番号履歴管理テーブル.電話番号
        and   通話履歴テーブル.通話日時 between 2015/06/01 and 2016/01/01
        and   通話履歴テーブル.通話日時 >= 電話番号履歴管理テーブル.登録日
        group by
            顧客テーブル.電話番号,
            通話履歴テーブル.アクション名,
            通話履歴テーブル.対応優先度
    ) サブクエリ
where サブクエリ.電話番号 = 電話番号履歴管理テーブル.電話番号
and   サブクエリ.最新登録日 = 電話番号履歴管理テーブル.登録日
and   電話番号履歴管理テーブル.区分ID = 区分管理テーブル.区分ID
/

条件で通話履歴テーブル.通話日時 >= 電話番号履歴管理テーブル.登録日、max(登録日)で最新の登録日を取得。
その後、電話番号履歴管理テーブルを結合させています。

電話番号履歴管理テーブルに同一登録日、別区分IDがあったら2行出ます(´・ω・`)

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

>単純にJOINするだけで実現出来て
これがどのようなものかによりますが、
2015/06/01~2016/01/01の条件を入れればいいのではないかと思いますが。
複数出てくるようなら電話番号履歴管理テーブルのselect でselect distinct ~にするといいですね。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

2015/01/01にXという区分で09011112222という電話番号が登録されており、かつ、 
2016/01/01にYという区分で09011112222という電話番号が登録されています
抽出対象期間が2015/06/01~2016/01/01の通話履歴

この条件で抽出する場合、期待結果は
・2015/06/01~2015/12/31までの09011112222の通話履歴には区分X
・2016/01/01の09011112222の通話履歴にだけ区分Y
が表示されれば良いということでしょうか?

恐らく相関サブクエリにせざるをえないので、抽出行が多いと遅くなるかも知れませんがこんな感じでどうでしょうか?

SELECT 顧客テーブル.電話番号
 , 通話履歴テーブル.アクション名
 , 通話履歴テーブル.対応優先度
 , kubun.区分 
FROM 通話履歴テーブル
LEFT JOIN 顧客テーブル ON 通話履歴テーブル.顧客ID = 顧客テーブル.顧客ID
LEFT JOIN (
 SELECT 区分管理テーブル.区分, 電話番号履歴管理テーブル.電話番号
 FROM 電話番号履歴管理テーブル
 LEFT JOIN 区分管理テーブル ON 電話番号履歴管理テーブル.区分ID = 区分管理テーブル.区分ID
 WHERE 電話番号履歴管理テーブル.電話番号 = 通話履歴テーブル.電話番号
 AND 電話番号履歴管理テーブル.登録日 <= 通話履歴テーブル.通話日時
 ORDER BY 電話番号履歴管理テーブル.登録日 desc
 LIMIT 1
) kubun ON kubun.電話番号 = 通話履歴テーブル.電話番号
WHERE 通話履歴テーブル.通話日時 BETWEEN '2015/06/01' AND '2016/01/01'


所で、

  1.  ユーザ毎に通話履歴は複数あると思いますが、CALL_IDや通話日時は出力しなくても良いのでしょうか?
  2.  2015/06/01に通話履歴があるのに、電話番号履歴管理テーブル に2015/06/01以前にその電話番号の登録が無いといった可能性は無いですよね?(このようなデータがあった場合、上記SQLでは区分に空白(NULL)が出力されます)

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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

  • ただいまの回答率 88.33%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る