- PR -

テーブルの外部結合

1
投稿者投稿内容
ドムイドム
会議室デビュー日: 2005/12/20
投稿数: 3
投稿日時: 2005-12-20 20:52
TABLE A
PID_ID ID Month Data
--------------------------
A 1 2005/10 100
B 1 2005/11 200
C 3 2005/11 300
D 3 2005/12 400

TABLE B
Month ID F1
-------------------
2005/10 1 aaa1
2005/10 2 bbb1
2005/10 3 ccc1
2005/10 4 ddd1
2005/11 1 aaa2
2005/11 2 bbb2
2005/11 4 ddd2
2005/12 3 ccc3

二つの表からMonthとIDをキーに結合したいのですが、
B.Monthはデータがない場合があるので直近(A.Month<=B.Month)
を取得し結合したいのです。
何かいい方法がありますでしょうか?
DataBaseはDB2ですが、SQLSERVERやORACLEのSQLでも
構わないので参考にさせていただきたいです。

結果
PID_ID ID Month Data F1
-------------------------------
A 1 2005/10 100 aaa1
B 1 2005/11 200 bbb2
C 3 2005/11 300 ccc3
D 3 2005/12 400 ccc3

ちなみにTABLE B が以下の状態のときは、結果のように
外部結合で抽出したいのです。

TABLE B
Month ID F1
-------------------
2005/10 1 aaa1
2005/10 2 bbb1
2005/10 3 ccc1
2005/10 4 ddd1
2005/11 1 aaa2
2005/11 2 bbb2
2005/11 4 ddd2

結果
PID_ID ID Month Data F1
-------------------------------
A 1 2005/10 100 aaa1
B 1 2005/11 200 bbb2
C 3 2005/11 300    
D 3 2005/12 400    
とんくま
ベテラン
会議室デビュー日: 2005/08/02
投稿数: 56
お住まい・勤務地: 東京
投稿日時: 2005-12-21 00:33
結果の2行目のDataがbbb2に成る理由が分かりません。
TABLE B には、
2005/11 1 aaa2
という、ID、Month共にマッチする行が有りますが、これとJoinせず、なぜIDの違う次の行の
2005/11 2 bbb2
とJoinするのですか?
 
PID_ID ID Month Data F1
-------------------------------
A 1 2005/10 100 aaa1
B 1 2005/11 200 bbb2 <----
C 3 2005/11 300 ccc3
D 3 2005/12 400 ccc3
ドムイドム
会議室デビュー日: 2005/12/20
投稿数: 3
投稿日時: 2005-12-21 10:10
すみません。指摘の通り間違っていました。

それで、元に戻ると自己解決できました。
ちょっと等符号が間違っているかもしれませんが下記のような感じで
実現できました。
SELECT * FROM A Left outer join B ON (A.ID=B.ID AND A.MONTH <= B.MONTH)
WHERE (B.MONTH >= (SELECT MAX(B2.MONTH) FROM B AS B2 WHERE B2.MONTH >= A.MONTH
AND B2.ID=B.ID) OR B.MONTH IS NULL)
とんくま
ベテラン
会議室デビュー日: 2005/08/02
投稿数: 56
お住まい・勤務地: 東京
投稿日時: 2005-12-22 21:40
こんな方法も有ります。
 
コード:
SELECT PID_ID, ID, Month, Data, F1
  FROM TABLE_A A
       LEFT OUTER JOIN
       TABLE
       (SELECT F1
          FROM TABLE_B B
         WHERE A.ID = B.ID
           AND B.Month >= A.Month
         ORDER BY
               B.Month
         FETCH FIRST 1 ROWS ONLY
       ) C
         ON 0=0;


とんくま
ベテラン
会議室デビュー日: 2005/08/02
投稿数: 56
お住まい・勤務地: 東京
投稿日時: 2005-12-22 21:58
ドムイドムさんのコードは、ちょっと修正が必要かと思います。
(特に、MAXでなくMIN)
 
SELECT A.*, F1 FROM A Left outer join B ON (A.ID=B.ID AND A.MONTH <= B.MONTH)
WHERE (B.MONTH = (SELECT MIN(B2.MONTH) FROM B AS B2 WHERE B2.MONTH >= A.MONTH
AND B2.ID=B.ID) OR B.MONTH IS NULL);
1

スキルアップ/キャリアアップ(JOB@IT)