Wednesday, 31 July 2019

[Db2 LUW] buggy (left) outer join?!?

Problem

Following queries lose against DB2 v11.1.1.1 fixpack number 1(Linux) lose the left row without match on the right side.
with G as
    (select   *
        from ADW_ETL.ETL_GDT_UNIQUE_KEY
        where TABLE_NAME in('BAP_KOMMUNIKATION',
                            'BAP_GESCHAEFTSVORFALL',
                            'BAP_GFSCHRITT',
                            'BAP_GFSCHRITTADD',
                            'BAP_AUFTRAG',
                            'BAP_AUFTRAGPRODUKT')
    )
  select   G.TABLE_NAME,
      C.FLAG_ACTIVE,
      G.STORE_FLAG,
      G.OGG_PACKER_FREQUENCY,
      C.DWH_TIME_DELAY,
      I.*
    from G
    left outer join ADW_STATMON.DWH_ODS_CTRL C
    on G.TABLE_NAME = C.DWH_ODSCTRL_GDT_NAME
    left outer join ADW_STATMON.DWH_INBOUND_REG I
    on I.DWH_TRG_TABLE_NAME = G.TABLE_NAME
    where nvl(I.DWH_REG_TS, current_timestamp) >= current_timestamp - 9
;
with G as
    (select   *
        from ADW_ETL.ETL_GDT_UNIQUE_KEY
        where TABLE_NAME in('BAP_KOMMUNIKATION',
                            'BAP_GESCHAEFTSVORFALL',
                            'BAP_GFSCHRITT',
                            'BAP_GFSCHRITTADD',
                            'BAP_AUFTRAG',
                            'BAP_AUFTRAGPRODUKT')
    )
  select   G.TABLE_NAME,
      C.FLAG_ACTIVE,
      G.STORE_FLAG,
      G.OGG_PACKER_FREQUENCY,
      C.DWH_TIME_DELAY,
      I.*
    from G
    left outer join ADW_STATMON.DWH_ODS_CTRL C
    on G.TABLE_NAME = C.DWH_ODSCTRL_GDT_NAME
    left outer join ADW_STATMON.DWH_INBOUND_REG I
    on I.DWH_TRG_TABLE_NAME = G.TABLE_NAME
    where I.DWH_REG_TS                         >= current_timestamp - 9
       or I.DWH_REG_TS                         is null
;
I am pretty sure it is not iso standard behavior, and to me counterintuitive for sure.

Solution

Either pack the filtering into with constructs or move the filter on the outer table (the one not necessarily retaining its records) into the on clause. Example for the latter:
with G as
    (select   *
        from ADW_ETL.ETL_GDT_UNIQUE_KEY
        where TABLE_NAME in('BAP_KOMMUNIKATION',
                            'BAP_GESCHAEFTSVORFALL',
                            'BAP_GFSCHRITT',
                            'BAP_GFSCHRITTADD',
                            'BAP_AUFTRAG',
                            'BAP_AUFTRAGPRODUKT')
    )
  select   G.TABLE_NAME,
      C.FLAG_ACTIVE,
      G.STORE_FLAG,
      G.OGG_PACKER_FREQUENCY,
      C.DWH_TIME_DELAY,
      I.*
    from G
    left outer join ADW_STATMON.DWH_ODS_CTRL C
    on G.TABLE_NAME = C.DWH_ODSCTRL_GDT_NAME
    left outer join ADW_STATMON.DWH_INBOUND_REG I
    on I.DWH_TRG_TABLE_NAME = G.TABLE_NAME
    and I.DWH_REG_TS >= current_timestamp - 9
;

No comments:

Post a Comment

[git] Create a local branch from another branch

From the active branch git checkout -b <LOCAL_BRANCH> From a donator branch git checkout -b <LOCAL_BRANCH> <DONATING_BRANCH...