복붙노트

[SQL] case 문 및 DECODE 동등한 있습니까?

SQL

case 문 및 DECODE 동등한 있습니까?

간단한 CASE 표현식 및 DECODE 기능은 동일 것 같다 그들에 의해 반환되는 결과는 동일해야한다는. 그들은 있습니까?

문서는 간단한 CASE 식에 대해 할 말이 다음을 가지고 :

디코드 기능이 비교, 설명은 동일 할 것으로 보인다.

(가) CASE 식은 단순한 동등 검색 할 때, 이것은 물론 동일하게 해석 될 수있다.

이 세 문장은 모두 같은 결과, 0을 반환하는 것 같다.

select case 1 when 2 then null else 0 end as simple_case
     , case when 1 = 2 then null else 0 end as searched_case
     , decode(1, 2, null, 0) as decode
  from dual

항상 같은 결과를 반환 간단한 CASE 표현식 및 DECODE 기능을 함 (특정 상황에서이 CASE 식을 검색)?

해결법

  1. ==============================

    1.벤 DECODE와 CASE의 차이점에 대한 긴 답을 작성했습니다. 그는 DECODE와 CASE는 이런 이유를 제대로 설명하지 않고 값 분명히 동일한 세트에 대해 서로 다른 데이터 유형을 반환 할 수 있음을 보여줍니다.

    벤 DECODE와 CASE의 차이점에 대한 긴 답을 작성했습니다. 그는 DECODE와 CASE는 이런 이유를 제대로 설명하지 않고 값 분명히 동일한 세트에 대해 서로 다른 데이터 유형을 반환 할 수 있음을 보여줍니다.

    DECODE ()는 매우 규범이다 : 항상 첫 번째 결과 매개 변수의 데이터 유형입니다. 오라클은 모든 다른 결과 매개 변수에 대한 암시 적 변환을 적용합니다. 첫 번째 결과 매개 변수가 숫자이고 기본 값은 날짜입니다 (말) 경우는 오류가 발생합니다.

    ORA-00932: inconsistent datatypes: expected NUMBER got DATE
    

    이것은 문서에 설명되어 있습니다 : 자세한 내용을 알아보십시오.

    첫 번째 시나리오에서는 첫 번째 결과 매개 변수는 오라클은 VARCHAR2로 처리하기로 결정 NULL이다. 우리가 첫 번째 결과 매개 변수가 숫자이고 기본 값이 null 디코딩이되도록 변경하면 () 문은 숫자를 반환합니다; 덤프 ()이 너무임을 증명한다.

    CASE는 모든 반환 값이 같은 데이터 유형을 가지고 있고, 그렇지 않은 경우 컴파일 오류가 발생합니다 주장하는 반면. 그것은 암시 적 변환을 적용하지 않습니다. 이것은 또한 문서에 덮여있다. 여기를 참조하십시오.

    차이점은이 아래로 비등. 다음 DECODE 문은 CASE 문을하지 않습니다 실행합니다 :

    select decode(1, 1, 1, '1') from dual;
    
    select case 1 when 1 then 1 else '1' end from dual;
    

    필수 SQL 바이올린.

  2. ==============================

    2.짧은 대답, 아니.

    짧은 대답, 아니.

    약간 긴 대답은 거의이다.

    각 문에서 얻은 결과는 동일 않은 것 같습니다. 우리는 데이터 유형을 평가하기 위해 DUMP 기능을 사용하는 경우 반환 당신은 내가 무슨 뜻인지 확인할 수 있습니다 :

    SQL> select dump(case 1 when 2 then null else 0 end) as simple_case
      2       , dump(case when 1 = 2 then null else 0 end) as searched_case
      3       , dump(decode(1, 2, null, 0)) as decode
      4    from dual;
    
    SIMPLE_CASE        SEARCHED_CASE      DECODE
    ------------------ ------------------ -----------------
    Typ=2 Len=1: 128   Typ=2 Len=1: 128   Typ=1 Len=1: 48
    

    SQL 바이올린

    디코드의 데이터 유형이 1 인 것을 당신은 두 개의 CASE 문 "반환"오라클의 데이터 형식 요약을 사용하여 2의 데이터 유형, DECODE는 VARCHAR2 (데이터 유형 1)를 반환하는 반면, CASE 문은 "반환되는 반면, 볼 수 있습니다 "번호 (데이터 타입 2).

    나는 이름이 제안으로, DECODE 함수이며 CASE들이 다르게 내부적으로 구현 된 의미있는하지 때문에이 문제가 발생 가정합니다. 이것을 증명하는 실제 방법은 없습니다.

    당신이 정말 아무 영향을주지 않는 것으로 생각할 수 있습니다. 당신이 수해야하는 경우 오라클은 암시 적으로 오른쪽 암시 적 변환 규칙에 따라 숫자를 문자로 변환 할 것인가? 이 데이터 유형이 동일해야 같은 연합은하지 않습니다 작업 중 하나 사실이 아니다; 오라클은 쉽게 당신을 위해 일을 할 어떤 암시 적 변환을하지 않습니다. 둘째, 여기에 오라클은 암시 적 변환에 대해 말씀입니다 :

    그것은 꽤 목록이 아니다; 하지만 끝에서 두 번째 포인트는 날짜에게 친절하게 저를 제공합니다. 우리는 이전 쿼리를 가지고 대신 날짜를 사용 하나로 변환하는 경우 :

    select case sysdate when trunc(sysdate) then null 
                        else sysdate 
           end as simple_case
         , case when sysdate = trunc(sysdate) then null 
                else sysdate 
           end as searched_case
         , decode(sysdate, trunc(sysdate), null, sysdate) as decode
      from dual;
    

    다시 한번, CASE 문은 데이터를 반환이 쿼리에 DUMP를 사용하는 (12), DATE를 입력합니다. 디코드는 VARCHAR2로 변환 SYSDATE 있습니다.

    SQL> select dump(case sysdate when trunc(sysdate) then null
      2                           else sysdate
      3              end) as simple_case
      4       , dump(case when sysdate = trunc(sysdate) then null
      5                   else sysdate
      6              end) as searched_case
      7       , dump(decode(sysdate, trunc(sysdate), null, sysdate)) as decode
      8    from dual;
    
    SIMPLE_CASE          
    ---------------------------------- 
    Typ=12 Len=7: 120,112,12,4,22,18,7 
    SEARCHED_CASE
    ---------------------------------- 
    Typ=12 Len=7: 120,112,12,4,22,18,7
    DECODE
    ---------------------------------- 
    Typ=1 Len=19: 50,48,49,50,45,49,50,45,48,52,32,50,49,58,49,55,58,48,54
    

    SQL 바이올린

    날짜가 세션 NLS_DATE_FORMAT을 사용하여 문자로 변환 된 것을 참고합니다 (SQL 바이올린에서).

    암시 적으로 문제를 일으킬 수있는 VARCHAR2로 변환되어있어 날짜를 가졌어요. 당신은 문자로 날짜를 변환, TO_CHAR를 사용하려는 경우 당신이 그것을 기대하지 않을 경우, 쿼리가 중단됩니다.

    SQL> select to_char( decode( sysdate
      2                         , trunc(sysdate), null
      3                         , sysdate )
      4                 , 'yyyy-mm-dd') as to_char
      5    from dual;
    select to_char( decode( sysdate
                    *
    ERROR at line 1:
    ORA-01722: invalid number
    

    SQL 바이올린

    마찬가지로, 날짜 연산은 더 이상 작동하지 않습니다 :

    SQL>
    SQL>
    SQL> select decode(sysdate, trunc(sysdate), null, sysdate) + 1 as decode
      2    from dual;
    select decode(sysdate, trunc(sysdate), null, sysdate) + 1 as decode
           *
    ERROR at line 1:
    ORA-01722: invalid number
    

    SQL 바이올린

    가능한 결과들 중 하나가 NULL이면 흥미롭게 DECODE 만 VARCHAR2로 표현으로 변환한다. 기본 값이 NULL 인 경우이 발생하지 않습니다. 예를 들어 :

    SQL> select decode(sysdate, sysdate, sysdate, null) as decode
      2    from dual;
    
    DECODE
    -------------------
    2012-12-04 21:18:32
    
    SQL> select dump(decode(sysdate, sysdate, sysdate, null)) as decode
      2    from dual;
    
    DECODE
    ------------------------------------------    
    Typ=13 Len=8: 220,7,12,4,21,18,32,0
    

    SQL 바이올린

    디코딩이 문서화하지만되어 있지 않으며 (13)의 데이터 형식을 반환 것을 참고, 나는, 저작물 등의 산술 날짜와 같은 날짜의 유형을 가정합니다.

    즉, 회피 DECODE 당신이 가능하게 할 수있는 경우에; 당신은 반드시 당신이 기대하고있는 데이터 유형을 얻을 수 있습니다. 톰 카이트를 인용 :

    그냥 DECODE와 CASE 사이에 두 개의 기능 차이가 완료합니다.

  3. ==============================

    3.난 내가 너무 늦게하지만 누군가 검색 희망이 도움이 될 수 있다면 있기 때문에 여기에 게시 나는 알고있다. 나는 같 대한 MSSQL 스크립트를 만들었습니다

    난 내가 너무 늦게하지만 누군가 검색 희망이 도움이 될 수 있다면 있기 때문에 여기에 게시 나는 알고있다. 나는 같 대한 MSSQL 스크립트를 만들었습니다

    Declare @Var varchar(399)='DECODE(MyColumnName,''A'',''Auto'',''M'',''Manual'')'
    
    Begin
    Declare @Count int, @Counter int=1
    Declare @TempTable table (ID int identity(1,1),Items varchar(500))
    Declare @SqlText varchar(max)
    Select @Var=Replace(Replace(@Var,'DECODE(',''),')','')
    
    Insert Into @TempTable
    Select * FROM [dbo].[Split] ( @Var ,',')
    --Select * from @TempTable
    Select @Count=Count(ID) from @TempTable
    
    While(@Counter<=@Count)
    Begin
        If(@Counter=1)
        Begin
        Select @SqlText='Case ' +Items from @TempTable Where ID=1
        End
    
        Else If(@Counter=@Count)
        Begin
        Select @SqlText+=' Then ' +Items +' End' from @TempTable Where ID=@Counter 
        End
    
        Else If(@Counter%2=0)
        Begin
        Select @SqlText +=' When ' +Items from @TempTable Where ID=@Counter
        End
    
        Else If(@Counter%2=1)
        Begin
        Select @SqlText +=' Then ' +Items from @TempTable Where ID=@Counter
        End
    
        Set @Counter+=1
    End
    
    Select @SqlText SqlServerCaseStatement
    End
    

    열을 쉼표로 구분 된 값을 분할하는 방법 - 당신이 그 기능을 필요로하는 경우 당신이 Romil의 답변을 참조 할 수 있습니다, 위의 스크립트에서 분할 기능을 사용

  4. from https://stackoverflow.com/questions/13712763/are-a-case-statement-and-a-decode-equivalent by cc-by-sa and MIT license