1

私は同僚のコードをリファクタリングしていますが、彼がカーソルを使用して「述語に一致する最新の行」を取得しているケースがいくつかあります。

彼の手法は、結合をカーソルとして記述し、日付フィールドの降順で並べ替え、カーソルを開き、最初の行を取得して、カーソルを閉じることです。

これには、これを駆動する結果セットの各行に対してカーソルを呼び出す必要があり、多くの行ではコストがかかります。私は参加できることを望んでいますが、相関サブクエリよりも安価なものは何ですか:

select a.id_shared_by_several_rows, a.foo from audit_trail a
where a.entry_date = (select max(a.entry_date) 
                     from audit_trail b 
                     where b.id_shared_by_several_rows = a.id_shared_by_several_rows 
                     );

これは一般的なニーズであるため、これを行う Oracle 分析関数があると思いますか?

4

4 に答える 4

2

これは、データに対して 1 回のパスのみを実行し、自己結合を実行せずにテーブルから必要な数の列を取得するために使用できます。

select DISTINCT
       a.id_shared_by_several_rows,
       FIRST_VALUE(a.foo)
       OVER (PARTITION BY a.id_shared_by_several_rows
             ORDER BY a.entry_date DESC)
       AS foo
from audit_trail a;
于 2010-04-27T02:05:16.003 に答える
1

ソート基準に従って行のシーケンス番号を識別するためのアナリティクス RANK、DENSE_RANK、および ROW_NUMBER があります。順序列に違いがない行の処理方法が異なります。[たとえば、1,1,3 または 1,1,2 または 1,2,3 が得られる場合があります。]

select index_name, column_name, column_position,
       rank() over (partition by table_name order by column_position) rnk,
       dense_rank() over (partition by table_name order by column_position) drnk,
       row_number() over (partition by table_name order by column_position) rn
from all_ind_columns
where index_owner = 'SYSMAN'
and table_name = 'MGMT_JOB_EXECUTION';

分析は選択された行で動作するため、不要な行をフィルターで除外するためにサブクエリ/インライン ビューが必要です。この例では、INDEX_NAME が共有識別子です。

select index_name, column_name
from
  (select index_name, column_name, column_position,
         row_number() over (partition by index_name order by column_position) rn
  from all_ind_columns
  where index_owner = 'SYSMAN'
  and table_name = 'MGMT_JOB_EXECUTION')
where rn = 1;
于 2010-04-27T00:54:32.937 に答える
1

私はあなたが使いたいと信じています

select
  max(id_shared_by_several_rows) keep (dense_rank first order by entry_date),
  max(foo                      ) keep (dense_rank first order by entry_date)
from
  audit_trail;
于 2010-04-27T07:18:45.707 に答える
0

これを試して:

select id_shared_by_several_rows, foo from (
select a.id_shared_by_several_rows, a.foo, a.entry_date, max(a.entry_date) over (partition by a.id_shared_by_several_rows) max_entry_date
from audit_trail_a
) where entry_date = max_entry_date
于 2010-04-27T06:57:01.483 に答える