0

Oracle 10 データベースに次のテーブルがあります。

ID と関連する日付をリストする TABLE_A:

ID         DATE
-----------------------
A1234    | 31-Dec-2008 
B5678    | 31-Dec-2009
A1234    | 31-Dec-2010 

月末に ID の評価を与える TABLE_B:

ID         RATING_DATE   RATING
--------------------------------
A1234    | 31-Dec-2008 | 3
A1234    | 31-Jan-2009 | 3
A1234    | 28-Feb-2009 | 3
A1234    | 31-Mar-2009 | 2
A1234    | 30-Apr-2009 | 2
A1234    | 31-May-2009 | 3
A1234    | 31-Jun-2009 | 2
A1234    | 31-Jan-2010 | 3
A1234    | 28-Feb-2010 | 3
B5678    | 31-Dec-2009 | 4
B5678    | 31-Dec-2010 | 4
B5678    | 31-Jan-2011 | 4
B5678    | 28-Feb-2011 | 4

必要なもの:

TABLE_AのすべてのID,ペアについて、[DATE, DATE + 12 months) の範囲内で最新のものとTABLE_BDATEのものを見つけたいと考えています。RATING_DATERATING

例:については、 2008 年 12 月 31 日から 2009 年 11 月 30 日までの最新のものを見つけたいと考えています。ここではA1234 | 31-Dec-2008RATING_DATERATINGA1234 | 31-Jun-2009 | 2

最新の を取得するための次の SQL がありますが、同様RATING_DATEに取得する方法がわかりません。RATING

SELECT      A.DATE, 
            A.ID, 
            MAX(TABLE_B.RATING_DATE)

FROM        TABLE_A A LEFT JOIN TABLE_B B
            ON
            A.ID = B.ID
            AND
            B.RATING_DATE >= A.DATE
            AND
            B.RATING_DATE < ADD_MONTHS(A.DATE, 12)

GROUP BY    A.DATE, 
            A.ID

ネストされた結合や他のサブクエリなしでこれを行う方法はありますか?

4

3 に答える 3

1

指定された要件を満たすクエリを次に示します。

SELECT DISTINCT a.id
     , a.date_
     , LAST_VALUE(b.rating_date) OVER (PARTITION BY a.id, a.date_ ORDER BY b.rating_date ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS last_rating_date
     , LAST_VALUE(b.rating)      OVER (PARTITION BY a.id, a.date_ ORDER BY b.rating_date ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS last_rating 
  FROM table_a a
  LEFT JOIN table_b b ON b.id = a.id 
       AND b.rating_date >= a.date_ AND b.rating_date < ADD_MONTHS(a.date_,12)
 ORDER BY a.id, a.date_

そして、ここに別のオプションがあります:

SELECT DISTINCT a.id
     , a.date_
     , MAX(b.rating_date) KEEP (DENSE_RANK LAST ORDER BY b.rating_date) OVER(PARTITION BY a.id, a.date_) as last_rating_date 
     , MAX(b.rating     ) KEEP (DENSE_RANK LAST ORDER BY b.rating_date) OVER(PARTITION BY a.id, a.date_) as last_rating
  FROM table_a a
  LEFT 
  JOIN table_b b ON b.id = a.id AND b.rating_date >= a.date_ AND b.rating_date < ADD_MONTHS(a.date_,12)
 ORDER BY a.id, a.date_

どちらも同じ結果セットを返します:

ID    DATE_      LAST_RATING_DATE LAST_RATING
----- ---------- ---------------- -----------
A1234 2008-12-31 2009-06-30                 2
A1234 2010-12-31                             
B5678 2009-12-31 2009-12-31                 4

注: テスト環境をセットアップするために、date列の名前を に変更しましtable_adate_

create table table_a (id varchar2(5), date_ date);
create table table_b (id varchar2(5), rating_date date, rating int);
alter session set nls_date_format = 'YYYY-MM-DD';
insert into table_a values ('A1234','2008-12-31');
insert into table_a values ('B5678','2009-12-31');
insert into table_a values ('A1234','2010-12-31');
insert into table_b values ('A1234','2008-12-31',3);
insert into table_b values ('A1234','2009-01-31',3);
insert into table_b values ('A1234','2009-02-28',3);
insert into table_b values ('A1234','2009-03-31',2);
insert into table_b values ('A1234','2009-04-30',2);
insert into table_b values ('A1234','2009-05-31',3);
insert into table_b values ('A1234','2009-06-30',2);
insert into table_b values ('A1234','2010-01-31',3);
insert into table_b values ('A1234','2010-02-28',3);
insert into table_b values ('B5678','2009-12-31',4);
insert into table_b values ('B5678','2010-12-31',4);
insert into table_b values ('B5678','2011-01-31',4);
insert into table_b values ('B5678','2011-02-28',4);
于 2012-06-20T20:45:51.673 に答える
0
MAX(B.RATING) KEEP (DENSE_RANK LAST ORDER BY RATING_DATE)

これは、先月に複数の評価がある場合、最大の評価が必要であることを前提としています。

FIRSTおよびLAST構文のドキュメントは次のとおりです。(ちなみに6月31日はありません。)

于 2012-06-20T18:45:57.067 に答える
0

SQLの特定の実装によりこれが簡単になるかもしれませんが、これはうまくいくはずです

SELECT v1.id, v1.myDate, v1.rating_date, b2.rating
FROM (SELECT a.id, a.myDate, MAX(b.rating_date) rating_date
      FROM tab_a a 
      LEFT JOIN tab_b b
      ON a.id = b.id
      AND b.rating_date >= a.myDate
      AND b.rating_date < ADD_MONTHS(a.myDate, 12)
      GROUP BY a.id, a.myDate) v1
LEFT JOIN tab_b b2
ON v1.id = b2.id
AND v1.rating_date = b2.rating_date
于 2012-06-20T14:55:34.013 に答える