Предполагая, что у меня есть следующая таблица:несколько подзапросов к со столом в Oracle
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
- РФН является примером для сложного случая, который только присваивает числа строкам, которые необходимы. Пожалуйста, не фиксируем на ней
from (select id, first_name, salary from employee) t
)
select
(select id from tt2 where rfn = 3) w
from dual
Он возвращает мне все идентификаторы, похожий на тот, где РФН = 3 (2500 строк 26)
А вот объяснить план
"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)"
--edit--
например у меня есть таблица с использованием:
"ID" "FIRST_NAME" "SALARY" "RFN" "22" "Jason" 1236.23 1 "24" "Jason" 1237.89 "26" "Jason" 1239.56 3
Я хочу, чтобы выбрать Зарплату от тех, кто с RFN = 1, что дает мне один номер 1236,23
Но я также хочу в том же запросе, чтобы выбрать Заработную плату enyone с RFN = 3, дает мне один номер 1239.56 ,
И так далее.
Но. Для каждого из этих запросов он делает FULL_TABLE_SCAN из N строк.
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)');
--edited для более clarification--
Ожидаемый результат от:
"ID" "FIRST_NAME" "SALARY" "RFN" "22" "Jason" 1236.23 1 "24" "Jason" 1237.89 "26" "Jason" 1239.56 3 "26" "Jack" 1249.56 6 "26" "Wiki" 119.56 8
salary salary1 salary2 name name2 1236.23 1249.56 119.56 Wiki Jack
из ~ следующего утверждения:
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
без 5 полных таблиц развертки 2500 строк
Этот код очень трудно следовать, возможно, потому что смысл его полностью скрыт абстракции, который вы используете. Оператор case, основанный на rownum, который вы комментируете как «Только пример», ничего не значит в контексте запроса, который вы выбираете.Можете ли вы объяснить смысл всего этого и какую проблему вы на самом деле пытаетесь решить здесь? –
Я создаю временную таблицу в WITH. Затем через CASE я назначаю конкретные разные числа для каждой строки в этой таблице. Чем я хочу выбрать определенные значения из этой таблицы. По вновь приобретенному номеру. – Fate
Вы все еще не объяснили, что вы на самом деле пытаетесь сделать. И почему ROW_NUMBER не работает, это рекомендуется для ROWNUM. Btw, «странная причина» не странная, это именно то, что вы написали: верните одинаковый идентификатор для всех строк. – dnoeth