Использование данных в других столбцах - PullRequest
0 голосов
/ 09 июля 2020

Моя таблица выглядит так, как показано ниже.

WITH mytable as (
    select 1 as serial, 'm1' as m, 10 as p, null as q from dual
    union
    select 2, 'm1', 12, null  from dual
    union
    select 3, 'm1', null, 5  from dual
    union
    select 4, 'm2', 20 , null from dual
    union
    select 5, 'm1', null, 6  from dual
    union  
    select 6, 'm2', null, 4   from dual
    ) select * from mytable;

Моя цель - получить P деление на Q. Проблема в том, что номинатор и знаменатель не находятся в одной строке. Более того, для каждого номинатора и знаменателя я хочу использовать строки с высоким значением в последовательном столбце, разделенном M. Ожидаемый результат:

M   Calculated_value
---  ----------------
m1    2               <--- 12 at the serial 2  divided by 6 in the rownumber 5
m2    5               <--- 20    "             4        "    5                  6

Ответы [ 3 ]

2 голосов
/ 09 июля 2020

Вот один вариант; код, который может вам понадобиться, начинается со строки # 14:

SQL> with mytable as (
  2  select 1 as serial, 'm1' as m, 10 as p, null as q from dual
  3  union
  4  select 2, 'm1', 12, null  from dual
  5  union
  6  select 3, 'm1', null, 5  from dual
  7  union
  8  select 4, 'm2', 20 , null from dual
  9  union
 10  select 5, 'm1', null, 6  from dual
 11  union
 12  select 6, 'm2', null, 4   from dual
 13  ),
 14  temp as
 15    (select m,
 16         first_value(p ignore nulls) over (partition by m order by p desc) p,
 17         first_value(q ignore nulls) over (partition by m order by q desc) q
 18     from mytable
 19    )
 20  select m,
 21    max(p) / max(q) calculated_value
 22  from temp
 23  group by m;

M  CALCULATED_VALUE
-- ----------------
m1                2
m2                5

SQL>
0 голосов
/ 12 июля 2020
with mytable as (
select 1 as serial, 'm1' as m, 10 as p, null as q from dual
union
select 2, 'm1', 12, null  from dual
union
select 3, 'm1', null, 5  from dual
union
select 4, 'm2', 20 , null from dual
union
select 5, 'm1', null, 6  from dual
union
select 6, 'm2', null, 4   from dual
)
select -- serial, m, p,q,p_found,q_found,
m,p_found/q_found
from
(
select serial,m,p,q
,row_number() over ( partition by m order by serial) as row_num
,first_value(p ignore nulls) over (partition by m order by serial desc ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) p_found
,first_value(q ignore nulls) over (partition by m order by serial desc ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) q_found
from mytable
) 
where row_num=1
;
0 голосов
/ 09 июля 2020

Похоже, вам нужно это:

select 
  m 
 ,max(p)keep(dense_rank first order by decode(p,null,null,serial) desc nulls last) max_p
 ,max(q)keep(dense_rank first order by decode(q,null,null,serial) desc nulls last) max_q
 ,max(p)keep(dense_rank first order by decode(p,null,null,serial) desc nulls last) 
  /
  max(q)keep(dense_rank first order by decode(q,null,null,serial) desc nulls last) 
  as result
from mytable
group by m;

M       MAX_P      MAX_Q     RESULT
-- ---------- ---------- ----------
m1         12          6          2
m2         20          4          5

Полный пример:

with mytable(serial,m,p,q) as (
select 1, 'm1', 10, null from dual
union
select 2, 'm1', 12, null from dual
union
select 3, 'm1', null, 5  from dual
union
select 4, 'm2', 20 , null from dual
union
select 5, 'm1', null, 6  from dual
union  
select 6, 'm2', null, 4   from dual
) 
select 
  m 
 ,max(p)keep(dense_rank first order by decode(p,null,null,serial) desc nulls last) max_p
 ,max(q)keep(dense_rank first order by decode(q,null,null,serial) desc nulls last) max_q
 ,max(p)keep(dense_rank first order by decode(p,null,null,serial) desc nulls last) 
  /
  max(q)keep(dense_rank first order by decode(q,null,null,serial) desc nulls last) 
  as result
from mytable
group by m;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...