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

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

ただいまの
回答率

87.48%

特定のテーブルにある複数条件のデータと一致するもののみを、別のテーブルから抜き出したい。

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 242

score 55

前提・実現したいこと

以下の図のように、二つのテーブル(table_joinとlink_table)から、link_tableにある
複数カラムを使って複数の条件(たとえばfile_name, sheet_nameがそれぞれ特定の値)を満たす
物のみをtable_joinから取り出したいです。
イメージ説明

追記:Unique、Primaryは、idにしか設定していません。

お聞きしたいことは下記2点です。
①「該当のソースコード」に記載の内容で書いたところ、エラーは出なかったのですが、
クエリとして上記のユースケースとして問題はないでしょうか。
(上の図ではすごく少ないデータのようなので問題なさそうに見えますが、実データは数十万件の
データであり、想定通りのクエリになっているかの確認が難しいです。)
②①では、table_joinを検索するキーを「id」で行っているのですが、「year」「tag」で行った場合(a.id, c.idを、(a.year and a.tag), (c.year and c.tag)に書き換えた)、検索される件数が変わってしまいます。紐づけ対象として行っているだけなので、結果は等価と思ったのですが、等価にならない理由として想定されるものはどういうことになりますでしょうか。

該当のソースコード

select a.id, a.a_data1, a.b_data1 from table_join a 
where 
 a.id 
in 
 (select c.id from link_table c where c.file_name = 'ほげほげ.xlsx' 
and
 c.sheet_name = 'a')
UNION
 select a.id, a.a_data1, a.b_data1
from 
 table_join a
where
 a.year >= 2015

試したこと

sqlに関して、やりたいことを検索し、MYSQL_workbenchなどでデバッグしてみた。

環境

MySQL workbench 8.0.19

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 1

checkベストアンサー

+1

①に対して、集計するというのがクエリーでは実現されていません。
union マージする機能で集計ではありません。

件数については、クエリーの性能を気にされていると思いますが、それは正しいクエリーであると同時に、インデックスも適切でなければなりません。

②について、table_joinとlink_tableの関係はidで1:n(※)なのでしょう。
これに対し、yearとtagではn:nになるので、件数が変わるのは当然です。
※テーブルが分かれているのが正しいなら1:nですが、1:1なら正規化されている状態ではありません。

やりたい事は概ね以下の様なSQLだと思います。

select a.year, a.tag, sum(a_data1), sum(b_data2), sum(b_data1), sum(b_data2)
from  table_join a inner join link_table c
      on a.id=c.id
where c.file_name = 'ほげほげ.xlsx' 
  and c.sheet_name = 'a'
  and c.year >= 2015
group by a.year, a.tag

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2021/05/31 01:40 編集

    すみません。追記しました。primaryとuniqueはidにしかありません。(mysqlが自動で出力する)
    ただ、運用の問題だと思うのですが、2テーブルのidがずれてしまうときがあり、同じIDでも別のものをさしてしまうことがある(片方のテーブルのIDの更新が追従しないときがある)ので、仕組み上一意になる、「yearとtagの組み合わせ」でonできないのかなと思った次第です。(year単独では一意にはならないですが、その場合、andを付けたとしても、onで結合したらまずいのでしょうか。)

    キャンセル

  • 2021/05/31 02:01

    「yearとtagの組み合わせ」が一意なら、idの代わりの結合条件にしても大丈夫ですけど、それなら何故テーブルを分けているんでしょうね。

    キャンセル

  • 2021/05/31 02:04

    2つのテーブルを別々のツールで変更しているからだと思います。
    (仕組み上はまずいとは思うのですが、いろいろとあってかえられない様なので…。
    ともあれ、ありがとうございます。UNIONは、pythonのpandasのところで図解があったので、なんとなくイメージがつかめました。確かに自分が書いたクエリではだめそうですね。ありがとうございます!)
    https://ai-inter1.com/pandas-dataframe_union/

    キャンセル

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

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

関連した質問

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