-1

次のテーブルがあると仮定します。

create table Employee
  (
  ID                 VARCHAR2(4 BYTE)         NOT NULL,
  First_Name         VARCHAR2(10 BYTE),
  Last_Name          VARCHAR2(10 BYTE),
  Start_Date         DATE,
  End_Date           DATE,
  Salary             Number(8,2),
  City               VARCHAR2(10 BYTE),
  Description        VARCHAR2(15 BYTE)
  )
  ;
insert into employee (
ID,  First_Name, Last_Name, Start_Date,                               
End_Date,                       Salary,  City,       Description)
select 21 + (level * 2) - 1,'Jason',    'Martin',  to_date('19960725','YYYYMMDD'), 
to_date ('20060725','YYYYMMDD'), 1234.56+level/3*5, 'Toronto',  'Programmer'
from dual
connect by level < 2501
;

次のクエリを実行しようとしているとき:

with tt2 as (
select t.*, 
case when rownum = 1 then 1 when rownum = 3 then 3 else null end rfn 

-- RFN は、必要な行にのみ番号を割り当てる複雑なケースの例です。直さないでください

from (select id, first_name, salary from employee) t
)

select  
(select id from tt2 where rfn = 3) w
from dual

rfn = 3 (26 の 2500 行) の ID に似たすべての ID が返されます。

そして、ここに説明計画があります

"PLAN_TABLE_OUTPUT"
"Plan hash value: 2716438026"
" "
"--------------------------------------------------------------------------------------------------------"
"| Id  | Operation                  | Name                      | Rows  | Bytes | Cost (%CPU)| Time     |"
"--------------------------------------------------------------------------------------------------------"
"|   0 | SELECT STATEMENT           |                           |  2500 |       |    12   (0)| 00:00:01 |"
"|*  1 |  VIEW                      |                           |  2500 | 42500 |     4   (0)| 00:00:01 |"
"|   2 |   TABLE ACCESS FULL        | SYS_TEMP_0FD9D6645_8CDDE2 |  2500 | 60000 |     4   (0)| 00:00:01 |"
"|   3 |  TEMP TABLE TRANSFORMATION |                           |       |       |            |          |"
"|   4 |   LOAD AS SELECT           | SYS_TEMP_0FD9D6645_8CDDE2 |       |       |            |          |"
"|   5 |    COUNT                   |                           |       |       |            |          |"
"|   6 |     TABLE ACCESS FULL      | EMPLOYEE                  |  2500 | 60000 |     8   (0)| 00:00:01 |"
"|   7 |   VIEW                     |                           |  2500 |       |     4   (0)| 00:00:01 |"
"|   8 |    TABLE ACCESS FULL       | SYS_TEMP_0FD9D6645_8CDDE2 |  2500 | 60000 |     4   (0)| 00:00:01 |"
"--------------------------------------------------------------------------------------------------------"
" "
"Predicate Information (identified by operation id):"
"---------------------------------------------------"
" "
"   1 - filter(""RFN""=3)"
" "
"Note"
"-----"
"   - dynamic sampling used for this statement (level=2)"

- 編集 -

たとえば、WITHにテーブルがあります:

「ID」「FIRST_NAME」「SALARY」「RFN」
"22" "ジェイソン" 1236.23 1
"24" "ジェイソン" 1237.89
"26" "ジェイソン" 1239.56 3

RFN = 1 の給与を選択して、単一の番号 1236.23 を取得したい

しかし、同じクエリで、RFN = 3 の enyone の Salary を選択して、単一の番号 1239.56 を得たいと考えています。

等々。

しかし。このクエリごとに、N 行の FULL_TABLE_SCAN が作成されます。

with tt2 as (
select t.*, case when rownum = 1 then 1 when rownum = 3 then 3 else null end rfn
from (select id, first_name, salary from employee) t
)
select  
(select salary from tt2 where rfn = 1) w,
(select salary from tt2 where rfn = 3) w
from dual

説明表:

('Plan hash value: 1823688231');
(' ');
('--------------------------------------------------------------------------------------------------------');
('| Id  | Operation                  | Name                      | Rows  | Bytes | Cost (%CPU)| Time     |');
('--------------------------------------------------------------------------------------------------------');
('|   0 | SELECT STATEMENT           |                           |  2500 |       |    12   (0)| 00:00:01 |');
('|*  1 |  VIEW                      |                           |  2500 | 40000 |     4   (0)| 00:00:01 |');
('|   2 |   TABLE ACCESS FULL        | SYS_TEMP_0FD9D6651_8CDDE2 |  2500 | 60000 |     4   (0)| 00:00:01 |');
('|*  3 |  VIEW                      |                           |  2500 | 40000 |     4   (0)| 00:00:01 |');
('|   4 |   TABLE ACCESS FULL        | SYS_TEMP_0FD9D6651_8CDDE2 |  2500 | 60000 |     4   (0)| 00:00:01 |');
('|   5 |  TEMP TABLE TRANSFORMATION |                           |       |       |            |          |');
('|   6 |   LOAD AS SELECT           | SYS_TEMP_0FD9D6651_8CDDE2 |       |       |            |          |');
('|   7 |    COUNT                   |                           |       |       |            |          |');
('|   8 |     TABLE ACCESS FULL      | EMPLOYEE                  |  2500 | 60000 |     8   (0)| 00:00:01 |');
('|   9 |   VIEW                     |                           |  2500 |       |     4   (0)| 00:00:01 |');
('|  10 |    TABLE ACCESS FULL       | SYS_TEMP_0FD9D6651_8CDDE2 |  2500 | 60000 |     4   (0)| 00:00:01 |');
('--------------------------------------------------------------------------------------------------------');
(' ');
('Predicate Information (identified by operation id):');
('---------------------------------------------------');
(' ');
('   1 - filter("RFN"=1)');
('   3 - filter("RFN"=3)');
(' ');
('Note');
('-----');
('   - dynamic sampling used for this statement (level=2)');

-- より明確にするために編集 --

からの期待される結果:

「ID」「FIRST_NAME」「SALARY」「RFN」
"22" "ジェイソン" 1236.23 1
"24" "ジェイソン" 1237.89
"26" "ジェイソン" 1239.56 3
"26" "ジャック" 1249.56 6
「26」 「ウィキ」 119.56 8
給与 給与1 給与2 名前 name2
1236.23 1249.56 119.56 ウィキジャック

~次のステートメントから:

with tt2 as (
select t.*, case when row_number() over (order by id) = 1 then 1 when row_number() over     (order by id) = 3 then 3 else null end rfn
from (select id, first_name, salary from employee) t
)
select 
(select salary from tt2 where rfn = 1) salary,
(select salary from tt2 where rfn = 6) salary1,
(select salary from tt2 where rfn = 8) salary2,
(select first_name from tt2 where rfn = 8) name,
(select first_name from tt2 where rfn = 6) name2

from dual

2500 行の 5 回のフル テーブル スキャンなし

4

1 に答える 1