programing

null이 아닌 마지막 양으로 null 값 채우기 - Oracle SQL

elecom 2023. 7. 22. 09:24
반응형

null이 아닌 마지막 양으로 null 값 채우기 - Oracle SQL

4개의 열이 있는 테이블이 있습니다.항목, 연도, 월, 금액.Amount(금액)에 대한 일부 값이 null이며, 이 경우 해당 값을 Null이 아닌 이전 Amount(금액) 값으로 채우려고 합니다.null 값이 하나만 있을 때 LAG 기능으로 쉽게 이 작업을 수행할 수 있지만 여러 개의 null 값이 연속적으로 있을 때는 어떻게 접근해야 할지 잘 모르겠습니다.다음은 내 쿼리에 추가할 항목에 대한 열이 추가된 테이블의 모양을 보여주는 다음과 같습니다.

Item | Year | Month | Amount | New_Amount
AAA  | 2013 | 01    | 100    | 100
AAA  | 2013 | 02    |        | 100
AAA  | 2013 | 03    | 150    | 150
AAA  | 2013 | 04    | 125    | 125
AAA  | 2013 | 05    |        | 125
AAA  | 2013 | 06    |        | 125
AAA  | 2013 | 07    |        | 125
AAA  | 2013 | 08    | 175    | 175

제가 원하는 것을 생산하기 위해 일할 수 없을 것 같은 두 가지 아이디어가 있었습니다.처음에는 LAG를 사용하려고 했지만 여러 개의 null 값이 연속적으로 있을 때는 이를 충족하지 못한다는 것을 알게 되었습니다.다음으로 FIRST_VALUE를 사용하려고 했지만, null 뒤에 값이 있고 null이 더 많은 경우에는 도움이 되지 않습니다.FIRST_VALUE 또는 다른 유사한 함수를 사용하여 마지막 null이 아닌 값을 검색할 수 있는 방법이 있습니까?

last_value with IGNOLLs는 Oracle 10g에서 정상적으로 작동합니다.

select item, year, month, amount, 
       last_value(amount ignore nulls) 
         over(partition by item 
              order by year, month 
              rows between unbounded preceding and 1 preceding) from tab;

rows between unbounded preceding and 1 preceding분석 기능의 창을 설정합니다.

이 경우 Oracle은 PARTITION BY(동일한 항목)에 정의된 그룹 내에서 처음부터 현재 행 - 1(1 이전)까지 LAST_VALUE를 검색합니다.

Oracle 10g에서 READ/LAG와 IGNORLS의 일반적인 대체품입니다.

그러나 오라클 11g을 사용하는 경우 고든 리노프의 답변에서 LAG를 사용할 수 있습니다("noke null"이 포함된 작은 오타가 있음).

여기 접근법이 있습니다.지정된 행 앞에 있는 null이 아닌 값의 수를 계산합니다.그런 다음 창 기능의 그룹으로 사용합니다.

select t.item, t.year, t.month, t.amount,
       max(t.amount) over (partition by t.item, grp) as new_amount
from (select t.*,
             count(Amount) over (Partition by item order by year, month) as grp
      from table t
     ) t;

Oracle 버전 11 이상에서는 다음을 사용할 수 있습니다.ignore nulls위해서lag()그리고.lead():

select t.item, t.year, t.month, t.amount,
       lag(t.amount ignore nulls) over (partition by t.item order by year, month) as new_amount
from table t

답이 상당히 안 좋습니다.

Item | Year | Month | Amount | New_Amount
AAA  | 2013 | 01    | 100    | null
AAA  | 2013 | 02    |        | 100
AAA  | 2013 | 03    | 150    | 100
AAA  | 2013 | 04    | 125    | 150
AAA  | 2013 | 05    |        | 125
AAA  | 2013 | 06    |        | 125
AAA  | 2013 | 07    |        | 125
AAA  | 2013 | 08    | 175    | 125

꽤 나쁜 결과입니다 :)

--

select item, year, month, amount, 
  last_value(amount ignore nulls) 
over(partition by item
  order by year, month
  rows between unbounded preceding and CURRENT ROW) from tab;

더 낫습니다

만약 당신이 다른 데이터베이스(예: sqlite)를 사용하고 있고 그것은 무시 null 함수가 없었습니다.당신이 참고할 수 있도록 다른 해결책을 여기에 게시합니다.

  1. 0/1 열을 사용하여 Null/Non-Null 데이터를 표시해야 합니다.
  2. 그런 다음 누적 요약 열을 생성하여 1단계에서 지시자 번호를 계산합니다. 이제 데이터가 이미 non_Null 데이터로 그룹화된 것처럼 보이는 것을 볼 수 있습니다.
  3. 마지막 단계로 누적 합계(2단계)에 의한 최대 함수 그룹을 사용하여 데이터(여기에 월이 있음)를 빈 항목으로 채우십시오.

이해를 돕기 위해 사진을 첨부합니다.

언급URL : https://stackoverflow.com/questions/26977267/fill-null-values-with-last-non-null-amount-oracle-sql

반응형