2017-01-14 1 views
0

인용구SQL 윈도우 함수 필터링

주어 이러한 요건 :

레이트 룩업 테이블 :

effective_start_date | effective_end_date | amount | rate_type 
---------------------------------------------------------------- 
2016-01-16 00:00:00 | 2016-02-15 00:00:00 | 0.10 | rate1 
2016-01-16 00:00:00 | 2016-02-15 00:00:00 | 156 | rate2 (annual) 
2016-02-16 00:00:00 | 2016-03-15 00:00:00 | 0.15 | rate1 

입력/소스 테이블 :

datetime   | person | qty | x | vatable 
------------------------------------------------- 
2016-01-15 00:00:00 |  p1 | 10 | x1 | Y 
2016-01-16 00:00:00 |  p1 | 10 | x1 | Y 
2016-01-16 00:00:00 |  p1 | 11 | x2 | N 
2016-01-16 01:00:00 |  p1 | 9 | x1 | Y 
2016-01-16 02:00:00 |  p2 | 10 | x1 | Y 
2016-02-15 00:00:00 |  p1 | 8 | x1 | Y 
2016-02-15 00:00:00 |  p1 | 8 | x2 | Y 
2016-02-16 00:00:00 |  p1 | 8 | x1 | Y 
2016-02-16 00:00:00 |  p1 | 7 | x2 | Y 

가 rate2이면 사용 된 : monthly_qty = PARAM 매월 수량의 합 (1월 16일에서 31일까지, 2월 1일부터 15일까지)
calculated_rate = 속도 량/12/monthly_qty
calculated_fee = calculated_rate * vatable와 수량의 수량
vatable_qty = 합 = Y VAT = calculated_rate * vatable_qty * PARAM가 = 일월 16 경우 0.12

- 이월 15

예상

출력 테이블 (기간 유효 시작 및 종료 날짜 바인딩)

datetime   | person | qty | monthly_qty | calc_rate | calc_fee  | vat_qty | vat 
-------------------------------------------------------------------------------------------------- 
2016-01-16 00:00:00 |  p1 | 21 | 40   | 156/12/40 | calc_rate * 21 | 10  | calc_rate * 10 * 0.12 
2016-01-16 01:00:00 |  p1 | 9 | 40   | 156/12/40 | calc_rate * 9 | 9  | calc_rate * 9 * 0.12 
2016-01-16 02:00:00 |  p2 | 10 | 40   | 156/12/40 | calc_rate * 10 | 10  | calc_rate * 10 * 0.12 
2016-02-15 00:00:00 |  p1 | 16 | 16   | 156/12/16 | calc_rate * 16 | 16  | calc_rate * 16 * 0.12 

(1) 1 월의 경우 1 월의 경우 실제 : 50, 예상 : 40 (10 + 11 + 9 + 10 만 해당)

편집 : 여기 내 업데이트 SQL이다 : (내가보기 사용하고) 내가 effective_start_daterate lookup tableeffective_end_date에 따라 윈도우 함수의 합을 얻을 필요가

select it.datetime, it.person, 'rate2'::varchar as rate_used, 
    sum(it.qty) as qty, 
    rl.amount, rl.effective_start_date, rl.effective_end_date, 
    sum(sum(it.qty)) over w_month as total_qty_per_month, 
    rl.amount/12/sum(sum(it.qty)) over w_month as calculated_rate, 
    ((rl.amount/12/sum(sum(it.qty)) over w_month) * sum(qty)) as calculated_fee, 
    sum(case when it.vatable = 'Y' then it.qty else 0 end) as vatable_qty 
    from input_table it 
    inner join rate_lookup_table rl on it.datetime between rl.effective_start_date and rl.effective_end_date 
    where it.person_type='PT1' and rl.rate_type = 'rate2' 
    group by it.datetime, it.person, rl.amount, rl.effective_start_date, rl.effective_end_date 
    window w_month as (partition by date_trunc('month', it.datetime)) 
    order by it.datetime 

합니다. 월의 시작

select it.datetime, it.person, it.qty, rl.amount, rl.rate_type, 
     rl.amount/12/sum(it.qty) over (partition by date_trunc('month', it.datetime)) as calculated_rate  
from rate_lookup_table rl 
    join input_table it on it.datetime between rl.effective_start_date and effective_end_date 
where rl.rate_type = 'rate2'; 

date_trunc('month', it.datetime) "정규화"날짜 :

+0

'effective_date'데이터 유형은 무엇입니까? 두 개의 DATE 열입니까? 그리고 어떤 데이터 타입이'input_table.datetime'입니까? 그것은 타임 스탬프인가? 질문을 편집 할 수 있고 두 테이블에 대한 create table 문을 추가 할 수 있습니까? –

+0

그들은 모두 시간대가없는 타임 스탬프입니다. – sophie

답변

2

는 지금까지 내가 말할 수있는, 당신은 한 달에 합계를 계산하기 위해이 betweenwindow function과 조인을 사용하는 것이 할 수있는 같은 달의 모든 값은 동일합니다. 따라서 창 함수는 같은 달의 모든 수량을 합산합니다.

는 샘플 데이터에 의하면,이 반환 :

datetime   | person | qty | amount | rate_type | calculated_rate 
--------------------+--------+-----+--------+-----------+---------------- 
2016-01-16 00:00:00 | p1  | 10 | 156 | rate2  |   0.45 
2016-01-16 01:00:00 | p1  | 9 | 156 | rate2  |   0.45 
2016-01-16 02:00:00 | p2  | 10 | 156 | rate2  |   0.45 
2016-02-15 00:00:00 | p1  | 8 | 156 | rate2  |   1.63 

calculated_fee 및 통은 calculated_rate에서 파생 될 수있다. 표현식을 반복하지 않으려면 파생 테이블을 사용할 수 있습니다.

select *, 
     calculated_rate * qty as calculated_fee, 
     calculated_rate * qty * 0.12 as vat 
from (
    select it.datetime, it.person, it.qty, rl.amount, rl.rate_type, 
     rl.amount/12/sum(it.qty) over (partition by date_trunc('month', it.datetime)) as calculated_rate  
    from rate_lookup_table rl 
    join input_table it on it.datetime between rl.effective_start_date and effective_end_date 
    where rl.rate_type = 'rate2' 
) t; 
+0

은 잘못된 'monthly_qty'를 받았고, rl.effective_start_date와 rl.effective_end_date 사이의 date_trunc ('month ', it.datetime) 도움이되는 것 같지 않습니다. – sophie