One Bug? CASE WHEN cause wrong result in outer join

Ran into a weird problem when reviewing the result of one normal view. Here come the details -- 

 

I got the following SQL statement which is quite a simple outer join query, 

 select
      items_table.item_key,
      items_table.crm_type,
      items_links.child_code,
      items_links.mother_code
 from
 (
SELECT
         name AS item_key,
        CASE 
            WHEN type='Mitigant' AND datamart_table='COLLATERAL'    THEN 'C' 
            WHEN type='Mitigant' AND datamart_table='GUARANTEE'     THEN 'G' 
            ELSE NULL
        END AS crm_type
FROM     lo_prod_template
WHERE  type = 'Mitigant'
)  items_table,
 (select   'dummy' as child_code, 'dummy' as mother_code from lo_prod_template) items_links
where
 items_table.item_key = items_links.child_code(+)

 

As there is no record in the table LO_PROD_TEMPALTE with name as "dummy", the query  (left outer join) should yeild "NULL" in the column child_code and mother_code, right? However, I got the following results presentd to me, 

ITEM_KEY                       C CHILD_CODE                     MOTHER_CODE
------------------------------ - ------------------------------ -----------------------
Real Estate                    C dummy                          dummy
DustinTestEntitySearch         G dummy                          dummy
Collateral Constrain by Min2   C dummy                          dummy
DonnieTest2                    C dummy                          dummy
DonnieTestGuarantee            G dummy                          dummy
Guarantee                      G dummy                          dummy
Guarantee Constrain Test Min   G dummy                          dummy
DonnieCollTest                 C dummy                          dummy
Search Test Min2               G dummy                          dummy
Search Coll Min                C dummy                          dummy

10 rows selected.

 

 This doesn't make any sense! Why does Oracle give me such result? After some trial-and-error work, I managed to get the expected results when removing the "CASE WHEN" clause in the query, 

SQL> select
  2        items_table.item_key,
  3        items_table.crm_type,
  4        items_links.child_code,
  5        items_links.mother_code
  6   from
  7   (
  8  SELECT
  9           name AS item_key,
 10           type AS crm_type
 11          /*CASE
 12              WHEN type='Mitigant' AND datamart_table='COLLATERAL'    THEN 'C'
 13              WHEN type='Mitigant' AND datamart_table='GUARANTEE'     THEN 'G'
 14              ELSE NULL
 15          END AS crm_type*/
 16  FROM     lo_prod_template
 17  WHERE  type = 'Mitigant'
 18  )  items_table,
 19   (select   'dummy' as child_code, 'dummy' as mother_code from lo_prod_template) items_links
 20  where
 21   items_table.item_key = items_links.child_code(+)
 22  /

ITEM_KEY                       CRM_TYPE                       CHILD_CODE                     MOTHER_CODE
------------------------------ ------------------------------ ------------------------------ --------------
Real Estate                    Mitigant
DustinTestEntitySearch         Mitigant
Collateral Constrain by Min2   Mitigant
DonnieTest2                    Mitigant
DonnieTestGuarantee            Mitigant
Guarantee                      Mitigant
Guarantee Constrain Test Min   Mitigant
DonnieCollTest                 Mitigant
Search Test Min2               Mitigant
Search Coll Min                Mitigant

10 rows selected.

SQL>

God... how could this happen? By the way, this behavior occurs in Oracle 11.2.0.2. 

SQL> select * from v$version where rownum=1;

BANNER
-------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 - 64bit Production

SQL>

 

I tried to reproduct this issue in Oracle 10.2.0.4, but this time CASE WHEN works well. See - 

SQL> select * from v$version where rownum=1;

BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - Prod

SQL>  select
  2        items_table.item_key,
  3        items_table.crm_type,
  4        items_links.child_code,
  5        items_links.mother_code
  6   from
  7   (
  8  SELECT
  9           name AS item_key,
 10         -- type as crm_type
 11          CASE
 12              WHEN type='Mitigant' AND datamart_table='COLLATERAL'    THEN 'C'
 13              WHEN type='Mitigant' AND datamart_table='GUARANTEE'     THEN 'G'
 14              ELSE NULL
 15          END AS crm_type
 16  FROM     lo_prod_template
 17  WHERE  type = 'Mitigant'
 18  )  items_table,
 19   (select   'dummy' as child_code, 'dummy' as mother_code from lo_prod_template) items_links
 20  where
 21   items_table.item_key = items_links.child_code(+);

ITEM_KEY                       C CHILD_CODE                     MOTHER_CODE
------------------------------ - ------------------------------ ------------------------------
Real Estate                    C
DustinTestEntitySearch         G
Collateral Constrain by Min2   C
DonnieTest2                    C
DonnieTestGuarantee            G
Guarantee                      G
Guarantee Constrain Test Min   G
DonnieCollTest                 C
Search Test Min2               G
Search Coll Min                C

10 rows selected.

SQL>

So, I suspect this could be one Oracle bug. 

 

posted @ 2012-09-03 20:55  FangwenYu  阅读(416)  评论(0编辑  收藏  举报