0

複数のテーブルからデータを取得する、かなり複雑な Oracle クエリがあります。結合の 1 つで、最高のレコードがあれば、それが欲しいです。したがって、左外部結合。開始日フィールドがあるため、ほとんどのレコードでは、最大開始日を取得すると最高のレコードが得られます。ただし、時折、開始日が同じレコードが存在することがあります。その場合、ステータス フィールドもあります。ただし、最適なステータス値は最小でも最大でもありません。'20' が最適、'05' または '40' が適切、'70' が最悪です。複数のレコードが返されたときに最適なオプションを見つけるようにクエリを設定するにはどうすればよいですか?

したがって、次のデータがある場合

Table1                       Table2
ID     otherData             ID      date      status    otherData
1      stuffa                1       jan-1-13  20        stuff93
2      stuff3                
3      stuff398              3       jan-2-13  20        stuff92
                             3       jan-2-13  70        stuff38
                             3       dec-3-12  20        stuff843

次のクエリを実行して取得できます。

1   stuffa    jan-1-13  20  stuff93
2   stuff3
3   stuff398  jan-2-13  20  stuff92

現在、私のクエリは次のとおりで、70 ステータスの 2 番目のレコード 3 を取得します。

select *
from table1 t1
left outer join
   (select *
    from table2 t2a
    where t2a.date = (select max(t2b.date)
                        from table2 t2b
                       where t2b.id = t2a.id)
    ) t2
  on (t2.id = t1.id)

selectステートメント内で順序付けられた列挙などを設定する方法はありますか? 何かのようなもの

rank() over ( partition by status order by ('20','05','40','70') rank
4

3 に答える 3

1

このようにして注文にステータスを追加します。

select *
  from (select t1.id,  t1.otherdata otherdatat1, t2.date, t2.status, t2.otherdata otherdatat2,
               rank() over (partition by t1.id order by t2.date desc,
                            case t2.status
                              when '20' then 1
                              when '05' then 2
                              when '40' then 3
                              when '70' then 4
                              else 5
                            end) rnk
          from table1 t1
               left outer join table2 t2
                            on t1.id = t2.id)
 where rnk = 1;
于 2013-02-15T17:43:57.057 に答える
1

順序付けられた列挙に要素がほとんどない場合は、これを使用できます

 ........         order by 
                  CASE status WHEN '20' THEN 1
                              WHEN '05' THEN 2
                              WHEN '40' THEN 3
                              WHEN '70' THEN 4
                  END) rank
于 2013-02-15T17:38:41.970 に答える
0

あなたは次のようなことをすることができます:

select t1.id, t1.otherdata, t2.dt, t2.status, t2.otherdata 
from table1 t1
left outer join (
    select t2a.*,
        row_number() over (partition by id order by dt desc,
            case status
                when '20' then 1
                when '05' then 2
                when '40' then 3
                when '70' then 4
                else 5 end) as rn
    from table2 t2a
    ) t2 on t2.id = t1.id and t2.rn = 1
order by t1.id;

これは、同じステータスの2つがある場合でも、1つのヒットが必要であることを前提としています。2つのうちどちらを取得するかは不確定です。両方が必要な場合は、rank()代わりに使用できます。どちらの方法でも、日付(最大値が必要なため降順)とステータス値の独自の順序に基づいて各レコードにランクを割り当て、結合条件で最高ランクのランクのみを選択します。

データを次のように設定します。

create table table1(id number, otherdata varchar2(10));
create table table2(id number, dt date, status varchar2(2), otherdata varchar2(10));

insert into table1 values(1, 'stuffa');
insert into table1 values(2, 'stuff3');
insert into table1 values(3, 'stuff398');

insert into table2 values(1, date '2013-01-01', '20', 'stuff93');
insert into table2 values(3, date '2013-01-02', '20', 'stuff92');
insert into table2 values(3, date '2013-01-02', '70', 'stuff38');
insert into table2 values(3, date '2012-12-03', '20', 'stuff843');

... これは与える:

        ID OTHERDATA  DT        STATUS OTHERDATA
---------- ---------- --------- ------ ----------
         1 stuffa     01-JAN-13 20     stuff93    
         2 stuff3                                 
         3 stuff398   02-JAN-13 20     stuff92
于 2013-02-15T17:41:11.313 に答える