2017-02-24 3 views
2

이전 레코드가 0이 아닌 값이 0 인 제품의 가격을 채우기 위해 쿼리를 작성하려고합니다. 간단한 상관 관계가있는 하위 쿼리를 작성하려고했지만 작동하지 않습니다.상관 관계 하위 쿼리에서 상위 1 또는 제한 1이 작동하지 않습니다.

var_1 = select * from "XYZ"."PRD_TEST" where price <> 0 order by period desc; 

var_out = select a.product,a.period, (select price from :var_1 b where a.product = b.product and a.period > b.period and b.period <> 0 limit 1) as price from "XYZ"."PRD_TEST" a; 

PRODUCT PERIOD PRICE 
A 1 100 
A 2 0 - to be filled with 100 
A 3 0 - to be filled with 100 
A 4 5 
A 5 0 - to be filled with 5 

하위 쿼리를 스칼라 함수로 바꾸려고했지만 매개 변수로 테이블을 사용하지 않았습니다.

왼쪽 외부 조인과 Row_number를 사용하여 출력을 얻으려고했지만 너무 비싸고 오랜 시간 실행됩니다.

난 당신이 HANA이 같은 스칼라 하위 쿼리 (선택 ... 제한 한 고려하지 스칼라를 사용할 수 있습니다 단지 TOP 1.

답변

1

같은 서브 쿼리 만 1 레코드를 가져올 수있는 최선의 방법을 찾고 있는데요, 불행하게도) :

Do begin 

var_1 = select * from ((Select 'A' product, '1' period, '100' price from sys.dummy) 
Union (Select 'A' product, '2' period, '0' price from sys.dummy) 
Union (Select 'A' product, '3' period, '0' price from sys.dummy) 
Union (Select 'A' product, '4' period, '5' price from sys.dummy) 
Union (Select 'A' product, '5' period, '0' price from sys.dummy)) order by period desc; 

var_out = (select a.product, 
      a.period, 
      (select max(price) 
       from :var_1 b 
       where a.product = b.product 
       and a.period > b.period 
       and b.period <> 0 
       and b.period = (select max(period) from :var_1 c 
           where a.product = c.product 
           AND a.period > c.period 
           and c.period <> 0 
           and c.price <> 0 
      )) as price 
       from :var_1 a where price = '0') 
union (select product, period, price from :var_1 where price <> '0'); 

select * from :var_out order by product, period; 
end 

코멘트 후 추가 sps12

에서 테스트. 왜 그냥 시도하지 않으시겠습니까? 그것은 매우 간단합니다. 호기심 때문에 HCP 시험판에서 시험해 보았습니다. 밀리언 행에 약 1 초가 걸렸습니다. 이전 기간에는 가격이없는 null 값을 가진 행을 피하기 위해 ifnull을 포함 시켰습니다.

drop table var_1; 
create column table var_1 as 
(
    select 
     cast ('Prod' || prd.GENERATED_PERIOD_START as nvarchar(20)) product, 
     cast (per.GENERATED_PERIOD_START as decimal(2)) period, 
     cast (case when rand() < '0.5' then rand() * '100' else '0' end 
      as decimal(5,2)) as price -- ~50% of price is 0 
     from series_generate_integer(1,0,1000000/13) as prd, --~1Mio records 
      series_generate_integer(1,0,13) as per --12 periods + period 0 
); 
merge delta of var_1; 
select * from var_1 
order by product, period 
limit 100; 
do begin sequential execution -- don't let parallel execution influence the runtime-measurement 
declare start_timestamp timestamp; 
start_timestamp = current_timestamp; 
var_out = (select a.product, 
      a.period, 
      ifnull ((select max(price) 
       from var_1 b 
       where a.product = b.product 
       and a.period > b.period 
       and b.period <> 0 
       and b.period = (select max(period) from var_1 c 
           where a.product = c.product 
           AND a.period > c.period 
           and c.period <> 0 
           and c.price <> 0 
      )),'0.0') as price 
       from var_1 a where price = '0') 
union (select product, period, price from var_1 where price <> '0'); 

select nano100_between(:start_timestamp, (select current_timestamp from dummy))/10000 as runtime_millisec from dummy; 

select * from :var_out 
order by product, period 
limit 100; 
end 
+0

도와 주셔서 감사합니다 크리스에 대한 많은 !! : 여기

는 코딩입니다 VAR_1 임시 테이블에 100 만 개가 넘는 항목이있는 경우 실적이 어떻게 될지 궁금하십니까? 중첩 된 하위 쿼리 (잘못 부른 경우 수정하십시오)로 인해 성능 문제가 발생합니까? – Gokul

+0

@gokul : 왜 단지 성능이 얼마나 좋은지 또는 나쁜지를 측정하지 않았습니까? 그리고 유스 케이스에서 좋은 성능은 무엇입니까? 오직 호기심에서부터 나는 테스트 데이터를 생성하고 실행 시간을 측정하는 코딩을 포함했다. HCP 재판에서 백만 기록 당 1 초가 그렇게 나쁘지 않습니까? 성명서에 대한 설명 계획이나 계획 마법사를 살펴 보는 것도 흥미로울 것입니다. 어쩌면 당신은 이것을 할 수 있고 질문에 어떤 가치를 추가 할 수 있습니다. 그리고 어쩌면 전문가 중 한 명이 윈도우 기능이나 다른 멋진 기능을 사용하여 좀 더 빠른 솔루션을 제안합니다. –

+0

안녕하세요 Chris, 변경 작업 중입니다. 쿼리의 성능을 확실히 업데이트 할 예정입니다. 다시 시도해 주셔서 감사합니다. – Gokul