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

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

ただいまの
回答率

88.09%

JOINされたテーブルと別テーブルとの比較方法が分からない

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,204

score 15

ガチ初心者です。

 前提条件

使用しているのはMySQL
テーブルA,Bのコピーが格納されているテーブルCopyA,CopyBがある。
テーブルA,Bは自動更新される。
テーブルCopyA,Bは手動更新をしないと更新が行われない。
なので、現在はテーブルA,BとテーブルCopyA,Bの中身には差異(テーブルA,Bの方が数値が大きい)がある。

 やっていること

①テーブルCopyA,CopyBからカラム1毎のカラムXのMAXの値を取得
②テーブルA,BのカラムXと①を比較
③テーブルA,BからカラムXが①以下のものを取得
④③を元にテーブルA,Bからカラム1,2,3,4を取得

 やりたいこと

②で手詰まりになったので、上記②の方法が知りたい。
(ようは別テーブルから取得した値をもとに比較をして、出てきた結果を出力したい。)

CREATE TABLE テーブルA,テーブルCopyA
(カラム1(varchar)(主),カラム2(varchar),カラムX(datetime))

CREATE TABLE テーブルB,テーブルCopyB
(カラム1(varchar)(主),カラム3(varchar),カラム4(varchar),カラムX(datetime))

現在の成果
SELECT
  テーブルA.カラム1,
  テーブルA.カラム2,
  テーブルB.カラム3,
  テーブルB.カラム4
FROM(
  SELECT カラム1,MAX(カラムX) AS カラムX
  FROM(
    SELECT カラム1,カラムX
      FROM テーブルCopyA
    UNION ALL
    SELECT カラム1,カラムX
      FROM テーブルCopyB
  )AS 別名1
  GROUP BY カラム1
)AS 別名2
INNER JOIN テーブルA
ON テーブルA.カラム1 = 別名2.カラム1
RIGHT JOIN テーブルB
ON テーブルB.カラム1 = テーブルA.カラム1;

現行のSQLを崩していただいてもかまいません。
質問に不備があるかと思いますので、指摘いただき次第追記していきます。
よろしくお願いします。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

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

  • sazi

    2018/11/20 16:44

    SQLを見直して修正して下さい。定義と名称があっていません。

    キャンセル

  • sazi

    2018/11/20 17:01

    テーブルB系でカラム1とかにまだなってます。

    キャンセル

  • hop

    2018/11/20 17:07

    カラム1はAもBも同じカラムなので、CREATE文を修正しました。

    キャンセル

回答 2

checkベストアンサー

0

COPYしたテーブルの最終更新日時以降に、変更のあった元テーブルのデータを抽出したいって事だと思うので
※追加も考慮

SELECT *
FROM (
        select * from テーブルA as A
        where カラムX >(select max(カラムx) from テーブルCopyA where カラム1=A.カラム1)
           or not exists(select 1 from テーブルCopyA where カラム1=A.カラム1)
    ) tA RIGHT JOIN (
        select * from テーブルB as B
        where カラムX >(select max(カラムx) from テーブルCopyB where カラム1=B.カラム1)
           or not exists(select 1 from テーブルCopyB where カラム1=B.カラム1)
    ) as tb 
    ON tB.カラム1 = tA.カラム1

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/11/20 17:34

    >COPYしたテーブルの最終更新日時以降に、変更のあった元テーブルのデータを抽出したいって事だと思うので

    くみ取っていただいてありがとうございます。
    質問が稚拙すぎて誤解をさせてしまいました。
    正しくはCopyテーブルの最終更新日以前のデータとの差分を取りたいのです。
    なので"where カラムX >(select"の不等号を<=に変更することで期待通りの結果が得られました。
    質問は解決しましたが問題が解決したわけではないので
    これからも質問を投稿すると思います。縁があればまたお願いします。
    ありがとうございました。

    キャンセル

  • 2018/11/20 17:45

    copy先の更新に漏れが無いかを確認するという事ですか。
    比較までは質問になかったので、当然記述は無いですけど、それぞれの対比の抽出なら全然別のSQLになるでしょう。

    キャンセル

0

カラムXはAが更新されたときに必ず更新されるのでしょうか?
カラムXがdateでは更新を細かく確認できないですよね
timestamp(datetime)にすればcopyAのカラムXの最大値より大きなカラムXをもつAの
データを抽出すればよいでしょう

 sample

create table tbl_a1(c1 varchar(20) not null primary key,c2 varchar(20),cx datetime default current_timestamp on update current_timestamp);
create table tbl_a2(c1 varchar(20) not null primary key,c2 varchar(20),cx datetime);
insert into tbl_a1 values('x001','y001','2018-11-01 00:00'),('x002','y002','2018-11-01 00:00'),('x003','y003','2018-11-01 00:00');
insert into tbl_a2 values('x001','y001','2018-11-01 00:00'),('x002','y002','2018-11-01 00:00'),('x003','y003','2018-11-01 00:00');


とりあえず同期されている状態にします。
ここからa1のデータをいじるとして

update tbl_a1 set c2='y002x' WHERE c1 = 'x002';
delete from tbl_a1 where c1=('x003');
insert into tbl_a1(c1,c2) values('x004','y004');


x002は更新されてcxが現在の日時に、x004のデータは新規データです
x003は削除なのでa1にデータが残りません
このデータをa1→a2にするには

insert into tbl_a2 
select * from tbl_a1 where cx>(select max(cx) from tbl_a2)
on duplicate key update c2=values(c2),cx=values(cx)


とします。
削除分まで同期する場合は

delete from tbl_a2 where not exists(select 1 from tbl_a1 where tbl_a2.c1=c1)


も実行しておいてください

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/11/20 16:58

    回答ありがとうございます。
    すみません、datetime型でした。
    質問を修正させていただきました。

    >timestamp(datetime)にすればcopyAのカラムXの最大値より大きなカラムXをもつAのデータを抽出すればよいでしょう

    この方法が分からないのです…。

    キャンセル

  • 2018/11/20 18:03

    追記しました

    キャンセル

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

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

関連した質問

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