Oracle에서 하위 쿼리를 사용하여 복잡한 표현식의 부분 값을 계산하는 것을 피할 수있는 방법이 있습니까?

아틸라 호르 바스

데이터 테이블에서 복잡한 식을 기반으로 값을 선택하려고합니다. 향후 유지 관리를 위해 전체 식을 하나로 작성하지 않고 대신 하위 선택에서 부분 결과를 계산합니다.

(쿼리는 그다지 중요하지 않습니다. 개념은이 샘플 쿼리를 비 개인화 했으므로 저를 참아주십시오. 프레젠테이션 목적으로 하나 또는 두 개의 문자 별칭을 사용하고 있습니다)

select t.*,
       (1 - nvl(min(t.O / t.MA) over(partition by t.fk_1, t.fk_2, t.fk_3, t.fk_4), 0)) *
       t.MA as V --value regulated by overhead
  from (select t.*,
               decode(sign(t.MA - t.M), 1, t.MA - t.M, to_number(null)) as O --overhead
          from (select t.*,
                       (1 - (max(t.PD) over(partition by t.fk_1, t.fk_2, t.fk_3, t.fk_4))) * t.ASZ as MA --value regulated by maximum percent difference
                  from (select t.*,
                               t.D / t.ASZ as PD --precent of diff      
                          from (select t.*,
                                       t.ASZ - t.BE as D --difference
                                  from (select l.fk_1, 
                                               l.fk_2, 
                                               l.fk_3, 
                                               l.fk_4,
                                               l.fk_5,
                                               l.BE, --Value that needs regulation by ratio on of Sum of values and maximum
                                               l.A, --Ratio
                                               l.SB, --Sum of values
                                               l.M, --Maximum of value
                                               decode((l.SB * l.A), 0, to_number(null), (l.SB * l.A)) as ASZ --Sum distributed as of given ratio      
                                          from vw_data l,
                                       ) t) t) t) t) t;

이것이 다음과 비슷한 방식으로 다시 작성 될 수 있는지 궁금합니다 (어떤 구문이 atm에서 작동하지 않습니다).

select l.fk_1,
       l.fk_2,
       l.fk_3,
       l.fk_4,
       l.fk_5,
       l.be, --Value that needs regulation by ratio on of Sum of values and maximum
       l.a, --Ratio
       l.sb, --Sum of values
       l.m, --Maximum of value
       decode((l.sb * l.a), 0, to_number(null), (l.sb * l.a)) as asz, --Sum distributed as of given ratio      
       asz - be as d, --difference
       d / asz as pd, --precent of diff  
       (1 - (max(pd) over(partition by l.fk_1, l.fk_2, l.fk_3, l.fk_4))) * asz as ma, --value regulated by maximum percent difference
       decode(sign(ma - l.m), 1, ma - l.m, to_number(null)) as o, --overhead                  
       (1 - nvl(min(o / ma) over(partition by l.fk_1, l.fk_2, l.fk_3, l.fk_4), 0)) * ma as v --value regulated by overhead
  from vw_data l

좀 더 나은 포맷을 선호하지만 훨씬 더 긴 포맷을 원한다면 :

SELECT t.*,
       ( 1 - nvl( MIN( t.O / t.MA ) OVER ( PARTITION BY t.fk_1,
                                                        t.fk_2,
                                                        t.fk_3,
                                                        t.fk_4 ),
                                           0 ) ) *
           t.MA AS V --value regulated by overhead
FROM ( SELECT t.*,
              DECODE( sign( t.MA - t.M ),
                      1,
                      t.MA - t.M,
                      TO_NUMBER( null ) ) AS O --overhead
          FROM ( SELECT t.*,
                       ( 1 - ( MAX( t.PD ) OVER ( PARTITION BY t.fk_1,
                                                               t.fk_2,
                                                               t.fk_3,
                                                               t.fk_4 ) ) ) *
                           t.ASZ AS MA --value regulated by maximum percent difference
                 FROM ( SELECT t.*,
                               t.D / t.ASZ AS PD --precent of diff      
                        FROM ( SELECT t.*,
                                      t.ASZ - t.BE AS D --difference
                                  FROM ( SELECT l.fk_1, 
                                                l.fk_2, 
                                                l.fk_3, 
                                                l.fk_4,
                                                l.fk_5,
                                                l.BE, --Value that needs regulation by ratio on of Sum of values and maximum
                                                l.A, --Ratio
                                                l.SB, --Sum of values
                                                l.M, --Maximum of value
                                                DECODE( ( l.SB * l.A ),
                                                        0,
                                                        TO_NUMBER( NULL ),
                                                        ( l.SB * l.A ) ) AS ASZ --Sum distributed as of given ratio      
                                         FROM vw_data l,
                                       ) t ) t ) t ) t ) t;

이것이 다음과 비슷한 방식으로 다시 작성 될 수 있는지 궁금합니다 (어떤 구문이 atm에서 작동하지 않습니다).

SELECT l.fk_1,
       l.fk_2,
       l.fk_3,
       l.fk_4,
       l.fk_5,
       l.be, --Value that needs regulation by ratio on of Sum of values and maximum
       l.a, --Ratio
       l.sb, --Sum of values
       l.m, --Maximum of value
       DECODE( ( l.sb * l.a ),
               0,
               TO_NUMBER( NULL ),
               ( l.sb * l.a ) ) AS asz, --Sum distributed as of given ratio      
       asz - be AS d, --difference
       d / asz AS pd, --precent of diff  
       ( 1 - ( MAX( pd ) OVER ( PARTITION BY l.fk_1,
                                             l.fk_2,
                                             l.fk_3,
                                             l.fk_4 ) ) ) * asz AS ma, --value regulated by maximum percent difference
       DECODE( SIGN ( ma - l.m ),
               1,
               ma - l.m,
               TO_NUMBER( NULL ) ) AS o, --overhead                  
       ( 1 - nvl( MIN( o / ma ) OVER ( PARTITION BY l.fk_1,
                                                    l.fk_2,
                                                    l.fk_3,
                                                    l.fk_4 ), 0 ) ) * ma AS v --value regulated by overhead
  FROM vw_data l
알렉스 풀

별로. 동일한 수준의 쿼리에서 열 별칭을 참조 할 수 없습니다. 단, order by clause이상적인 쿼리는 슬프게도 불가능합니다. 예를 들어, 때 수행하려고 asz - be AS d(가) asz기본 테이블에서 해당 이름을 가진 열이 없기 때문에 인식되지 않고, 그 이름을 가진 별칭은 아직 존재하지 않습니다.

문서에서 :

c_alias
열 식의 별칭을 지정합니다. Oracle Database는 결과 집합의 열 머리글에이 별칭을 사용합니다. AS 키워드는 선택 사항입니다. 별칭은 쿼리 기간 동안 선택 목록 항목의 이름을 효과적으로 바꿉니다. 별칭은 order_by_clause 에서 사용할 수 있지만 쿼리의 다른 절에서는 사용할 수 없습니다.

주위에 대한 다양한 설명이 왜, 이와 같은 , 그들은 당신이 어디에, 그룹 또는 HAVING 절 A의 별칭을 사용할 수없는 이유에 대해 경향이 있지만. 동일한 선택 목록 내에서 다시 사용할 수없는 이유가 명확하지 않을 수 있습니다. 그러나 표현식의 별칭을 실제 열 이름과 동일하게 할 수 있으므로 다음과 같은 작업을 시도 할 수 있습니다.

select abs(be) as be, be - asz as d, ...

... 추가 모호성의 가능성이 be있습니다. 계산에서 원래 열 값을 참조하거나 별칭의 수정 된 값을 참조합니까? 물론 당신이 그렇게하겠다고 제안하는 것은 아닙니다. 약간 더 가능성이있는 것은 누군가가라는 열을 추가하기 위해 테이블을 변경하여 asz기존 쿼리를 혼동 할 수 있다는 것입니다. 그러나 이유가 무엇이든 동일한 선택 목록에서 열 별칭을 참조 할 수도 없습니다.

중첩 된 하위 쿼리 대신 하위 쿼리 팩토링을 사용할 수 있습니다. 이는 적어도 중간 단계를 순서대로 나열 할 수있게 해주므로 좀 더 직관적 일 수 있습니다. 하지만 그다지 도움이되지는 않습니다.

with t1 as (
  select l.fk_1, 
         l.fk_2, 
         l.fk_3, 
         l.fk_4,
         l.fk_5,
         l.BE, --Value that needs regulation by ratio on of Sum of values and maximum
         l.A, --Ratio
         l.SB, --Sum of values
         l.M, --Maximum of value
         decode((l.SB * l.A), 0, to_number(null), (l.SB * l.A)) as ASZ --Sum distributed as of given ratio      
  from vw_data l),
t2 as (
  select t1.*,
         t1.ASZ - t1.BE as D --difference
  from t1),
t3 as (
  select t2.*,
         t2.D / t2.ASZ as PD --precent of diff
  from t2),
t4 as (
  select t3.*,
         (1 - (max(t3.PD) over (partition by t3.fk_1, t3.fk_2, t3.fk_3, t3.fk_4)))
           * t3.ASZ as MA --value regulated by maximum percent difference
  from t3),
t5 as (
  select t4.*,
         decode(sign(t4.MA - t4.M), 1, t4.MA - t4.M, to_number(null)) as O --overhead
  from t4)
select t5.*, 
       (1 - nvl(min(t5.O / t5.MA) over(partition by t5.fk_1, t5.fk_2, t5.fk_3, t5.fk_4), 0))
         * t5.MA as V --value regulated by overhead
from t5;

이 시나리오에서는 다소 선호하는 문제입니다.

그렇지 않으면 단일 수준의 쿼리를 고수하고 모든 계산을 여러 번 반복해야하므로 피하려고합니다. 또는 다양한 계산을 수행하는 함수로드를 생성합니다 (두 계산 사이에 반복). 추가 오버 헤드가 발생하고 훨씬 더 불투명 해집니다.

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

Related 관련 기사

뜨겁다태그

보관