prosource

Oracle에서 Greatest 함수에 Null 처리 중

probook 2023. 6. 27. 22:22
반응형

Oracle에서 Greatest 함수에 Null 처리 중

두 열의 두 날짜를 비교하여 가장 큰 날짜를 얻은 다음 날짜 값과 비교하려고 합니다.두 열에는 NULL 값도 포함될 수 있습니다.

예를 들어 저는 아래의 출력을 원합니다.

Col A         Col  B          OUTPUT
---------------------------------------
 NULL          NULL            NULL
 09/21/2013    01/02/2012      09/21/2013
 NULL          01/03/2013      01/03/2013 
 01/03/2013    NULL            01/03/2013 

최고의 기능을 어떻게 사용합니까, 아니면 다른 기능이 있는 경우에는?저는 다른 날짜와 비교하기 위해 다시 출력을 사용하고 있습니다.

당신의 질문은 특히 두 개의 열을 포함하지만, 저는 제가 필요로 하는 상황에 부딪혔습니다.GREATEST/LEAST세 개 이상의 열로 구성됩니다.이러한 시나리오에서 사용할 수 있습니다.COALESCE원하는 열로 솔루션을 확장합니다.

다음은 세 개의 열이 있는 예제입니다.a,b,그리고.c:

GREATEST(
    COALESCE(a, b, c),
    COALESCE(b, c, a),
    COALESCE(c, a, b)
)

열 순서는 다음과 같습니다.COALESCE각 입력 열이 첫 번째 요소가 되도록 변경됩니다.COALESCE한 번쯤은모든 입력 열이 NULL인 경우에만 NULL이 반환됩니다.

"일반 솔루션"에서 다음의 수COALESCE문은 입력 열 수와 동일합니다.

GREATEST(
    COALESCE(col1, col2, col3, col4, ....),
    COALESCE(col2, col3, col4, ...., col1),
    COALESCE(col3, col4, ...., col1, col2),
    COALESCE(col4, ...., col1, col2, col3),
    COALESCE(...., col1, col2, col3, col4),
    ...
)

다음을 시도할 수 있습니다.

SELECT cola, colb, COALESCE( GREATEST( cola, colb ), cola, colb ) AS output
  FROM yourtable;

이유는COALESCE()그것은GREATEST()돌아온다NULL매개 변수 중 하나가 다음과 같은 경우NULL.

를 처리하는 데 사용하는 다른 버전null값:

select cola, colb, 
  case when cola is null and colb is null then null
    when cola is null then colb
    when colb is null then cola
    else greatest(cola, colb)
  end as output
from <table>;

COLA       COLB       OUTPUT   
---------- ---------- ----------

09/21/2013 01/02/2012 09/21/2013 
           01/03/2013 01/03/2013 
01/03/2013            01/03/2013 

NVL 함수를 사용하여 열이 NULL을 반환할 가능성을 제거할 수 있습니다.NULL 값은 테이블에 발생할 가능성이 있는 날짜보다 이른 날짜로 대체합니다.

SELECT GREATEST(NVL(A,TO_DATE('01/01/1800','MM/DD/YYYY')), 
                NVL(B,TO_DATE('01/01/1800','MM/DD/YYYY'))) AS OUTPUT
FROM ...

그러면 GREATE 함수는 하나 이상의 열에 NULL이 포함된 경우 실수로 NULL을 반환하지 않고 제공된 날짜 목록에서 가장 최근의 날짜(최대 날짜)를 반환합니다.

선택 항목에 Oracle 구조 사용:

SELECT COLA, COLB, CASE
  WHEN (COLA >= COLB OR COLB IS NULL)
    THEN COLA
  ELSE COLB
  END
  AS OUTPUT
FROM ...

비교할 열이 많은 경우(2개 또는 3개 이상) 다양한 CASE 조합을 모두 처리하기가 어려울 수 있습니다.시도할 수 있습니다(11g):

with x as (
  select 1 as id, sysdate - 30 as col1, sysdate-50 as col2, sysdate-20 as col3,null as col4, sysdate-1 as col5 from dual
  union
  select 2 as id, sysdate - 10 as col1, sysdate-20 as col2, null as col3,null as col4, sysdate-35 as col5 from dual
  union
  select 3 as id, null as col1, null as col2, null as col3, null as col4, null as col5 from dual
)
select id, max(dates)
from x
UNPIVOT INCLUDE NULLS
(dates FOR colname IN (col1,col2,col3,col4,col5))
group by id

비슷한 것

SELECT CASE WHEN ColA is NULL and ColB is NULL then NULL
WHEN coalesce(ColA, '01/01/1753')>coalesce(ColB, '01/01/1753') then ColA
ELSE ColB END as Output

제가 해봤는데..검색 후 발견된

WITH ABC AS ( SELECT NULL AS col1 , NULL AS col2 FROM dual UNION
 SELECT NULL , DATE'2013-08-12' FROM dual UNION
  SELECT  DATE'2013-08-12' , NULL FROM dual UNION
   SELECT  DATE'2013-08-12',  DATE'2013-09-12' FROM dual)

   SELECT col1, col2 , substr(greatest('x'||col1,'x'||col2),2)
      FROM ABC;

NVL을 사용하여 이 문제를 해결하지만 비교된 열 수에 따라 복잡성이 증가합니다.

select A.*, *greatest("COL A", "COL B") "DIRECT COMPARE"*, **greatest(nvl("COL A", "COL B"), nvl("COL B", "COL A")) "NVL COMPARE"**
from (
SELECT NULL "COL A", SYSDATE "COL B", SYSDATE "NEEDED RESULT" FROM DUAL UNION
SELECT SYSDATE - 180 , NULL  , SYSDATE - 180 FROM DUAL UNION
SELECT SYSDATE - 180 , SYSDATE , SYSDATE FROM DUAL ) A;

언급URL : https://stackoverflow.com/questions/19186283/handling-null-in-greatest-function-in-oracle

반응형