2014-11-27 1 views
0

SQL 쿼리에서 추출한 테이블 (CURRENT)이 있습니다. 각 벤치 마크에는 두 개의 데이터 포인트가 있습니다. 두 데이터 포인트의 차이 (즉, 최신 데이터 포인트 - 최근 데이터 포인트)를 계산하고 그 결과를 행 옆에 표시해야합니다.2 열마다 계산을 수행하고 그룹에 대한 결과를 표시합니다.

나는 그것이 그룹과 관련이 있다고 생각하지만 이것은 SQL에서 가장 약한 영역이며 그룹화 된 행과 함께 표시되도록 결과를 반환하는 방법을 모르겠다. 나는 "벤치 마크에 의한 그룹"을 수행하여 차이를 계산 한 다음 MAX (VALUE) - Min (VALUE)를 가졌지 만 표지판을 알 수있는 방법이 없으므로이 방법이 멍청하다는 것을 깨달았습니다. 내가 그렇게 할 수 있다고해도 계산 된 값을 표시하는 방법을 모르겠습니다. 어떤 assitance pls?

감사합니다. (오라클 PLS) 아마이

CURRENT \t \t \t \t 
 
\t DATEF \t  BENCHMARK \t VALUE \t 
 
\t 31-Jul-14 \t A \t  100 \t 
 
\t 31-Aug-14 \t A \t  101 \t 
 
\t 31-Jul-14 \t B \t  101 \t 
 
\t 31-Aug-14 \t B \t  99 \t 
 
\t 31-Jul-14 \t C \t  100 \t 
 
\t 31-Aug-14 \t C \t  101 \t 
 
\t 31-Jul-14 \t D \t  100 \t 
 
\t 31-Aug-14 \t D \t  100 \t 
 
\t 31-Jul-14 \t E \t  101 \t 
 
\t 31-Aug-14 \t E \t  102 \t 
 
\t \t \t \t 
 

 
EITHER THIS: \t \t \t \t 
 
\t \t \t \t 
 
\t DATEF \t  BENCHMARK \t VALUE \t DIFFERENCE 
 
\t 31-Jul-14 \t A \t   100 \t  1 
 
\t 31-Aug-14 \t A \t   101 \t  1 
 
\t 31-Jul-14 \t B \t   101  -2 
 
\t 31-Aug-14 \t B   \t 99 \t  -2 
 
\t 31-Jul-14 \t C \t   100 \t  1 
 
\t 31-Aug-14 \t C   \t 101 \t  1 
 
\t 31-Jul-14 \t D \t   100 \t  0 
 
\t 31-Aug-14 \t D   \t 100 \t  0 
 
\t 31-Jul-14 \t E \t   101 \t  1 
 
\t 31-Aug-14 \t E \t   102 \t  1 
 

 

 

 
OR THIS: \t \t \t \t 
 
\t \t \t \t 
 
\t DATEF \t  BENCHMARK \t VALUE \t DIFFERENCE 
 
\t 31-Jul-14 \t A \t   100 \t  
 
\t 31-Aug-14 \t A \t   101 \t  1 
 
\t 31-Jul-14 \t B \t   101  
 
\t 31-Aug-14 \t B   \t 99 \t  -2 
 
\t 31-Jul-14 \t C \t   100 \t  
 
\t 31-Aug-14 \t C   \t 101 \t  1 
 
\t 31-Jul-14 \t D \t   100 \t  
 
\t 31-Aug-14 \t D   \t 100 \t  0 
 
\t 31-Jul-14 \t E \t   101 \t  
 
\t 31-Aug-14 \t E \t   102 \t  1

답변

1

오라클은 정확히 당신이 필요로하는 것처럼 보이는 FIRST_VALUE()LAST_VALUE() 기능을 제공합니다. 문제는 집계가 아닌 분석/창 함수 중 하나입니다.

select c.*, 
     (last_value(value) over (partition by benchmark order by datef range between unbounded preceding and unbounded following) - 
     first_value(value) over (partition by benchmark order by datef range between unbounded preceding and unbounded following) 
     ) as difference 
from current c; 

편집 : 그러나 내가 할 최대 (값) 무엇을하는지 이해가 안 돼요, 내가이 작품도 생각

select c.*, 
     (first_value(value) over (partition by benchmark order by datef desc) - 
     first_value(value) over (partition by benchmark order by datef) 
     ) as difference 
from current c; 
+0

thnanks. 그 작품은 내가 원하는 ... 그러나 나는 LAST_VALUE를 올바르게 반환하기 위해 "UNBOUNDED PRCEDING AND UNBOUNDED FOLLING"범위를 추가해야합니다. 이 절은 최종 사용자에게 설명하기 다소 어렵습니다. – theluncheonmeat

+0

@theluncheonmeat. . . 그것은 미묘한 문제입니다. 'first_value()'를 사용하고 정렬 순서를 바꾸려면'range' 절이 필요하다고 생각하지 않습니다. 'order by'는 해석 함수를 누적 적으로 만들고, 암묵적으로 '제한이없는 선행 행과 현재 행 사이의 범위'를 추가합니다. 누적 된 버전이 원하는 것을 리턴하도록'range'가이를 오버라이드하거나'first_value'를 사용해야합니다. –

0

?

select benchmark, max(value) keep (dense_rank first order by datef) - 
        max(value) keep (dense_rank last order by datef) difference 
    from current 
group by benchmark 

이 쿼리는 최소한의 datef에 대한 value을 가지고 최대 datef 위해 value에서 뺍니다. 그것은 당신이 원하는 것입니까?

또는 lag/lead 분석 기능을 사용할 수도 있습니다.

+0

:

은 또는, 당신이 위를 단순화 할 수 있습니다 생각합니다. "dense_rank firstfirst order by datef"는 이미 첫 번째 정렬 된 결과를 나타 내기 때문에 max (value)가 아닌 value를 넣어야하는 이유는 무엇입니까? – theluncheonmeat

+0

@theluncheonmeat 식 'max (value) keep (dense_rank first order by datef)'는 "datef'의 테이블을 정렬하고'datef'가 최대 인 행에서 최대 'value'를 취합니다" – Dmitry

관련 문제