简体   繁体   中英

Why left outer join works like inner join on ABAP CDS view and a custom table?

I have created an ABAP CDS view using ACDOCA , BSID , MARA , MAKT and such tables. Now my CDS view contains list of customers along with their outstanding (FI) documents.

Against these customers, FI documents and certain more parameters, I am maintaining certain data in a custom table.

Now using left outer join I want to connect this CDS view with custom table. The problem now is that this join is working like inner join, so if my custom table is blank my output is displaying without values whereas it should be displaying CDS view as it is, and custom table fields as blank.

Now based on similar issues on web I did research and found some useful points:

  1. all conditions on right table are included at most in ON join condition

  2. tried to include null values from right side custom table as well.

  3. tried using just one parameter on join condition to see the result (still working as inner join)

Here is my complete select statement, where:

  1. ZPD1 is my ABAP CDS view of ACDOCA , BSDI ... tables

  2. ZPD_HSL is an ABAP CDS view for customer wise GL amount calculation.

  3. ZFI_PDRATE_MAP is my custom table which contains rate for customer / FI docs combination.

What could be a misstep in this statement?

SELECT
      FROM ZPD1( PBUKRS   = @BUKRS-LOW ,
                 POSTFROM = @COL_DATE-LOW ,
                 POSTTO   = @COL_DATE-HIGH ) AS A

      LEFT OUTER JOIN ZFI_PDRATE_MAP  AS F
            ON  A~PROD_CATEGORY =  F~PROD_CATEGORY
            AND A~OD_DATE       GE F~POST_DT_FROM 
            AND A~OD_DATE       LE F~POST_DT_TO
            AND F~COL_DT_FROM   GE @COL_DATE-LOW  
            AND F~COL_DT_TO     LE @COL_DATE-HIGH
            AND F~SALES_OFFICE  =  @VKBUR-LOW
            AND CASE WHEN A~ARREAR_DAYS <= 0 THEN 'NOD' 
                     WHEN A~ARREAR_DAYS > 0 THEN 'OD' 
                END             =  F~OD

      INNER JOIN KNA1 AS H 
            ON H~KUNNR = A~KUNNR

      INNER JOIN TVKBT AS I 
            ON  I~VKBUR = F~SALES_OFFICE 
            AND I~SPRAS = @SY-LANGU

      LEFT OUTER JOIN SKAT AS J 
            ON  J~SAKNR = A~HKONT 
            AND J~SPRAS = 'E' 
            AND J~KTOPL = '1000'

      LEFT OUTER JOIN MAKT AS K 
            ON  K~MATNR = A~MATNR 
            AND K~SPRAS = 'E'

      LEFT OUTER JOIN T001W AS L 
             ON L~WERKS = A~WERKS


      FIELDS
      A~RBUKRS  AS BUKRS,
      A~KUNNR,
      H~NAME1,
      F~SALES_OFFICE,
      I~BEZEI,
      A~BELNR AS COL_BELNR,
      A~GJAHR AS COL_GJAHR,
      A~HSL AS COL_AMT,
      A~BUDAT AS COL_DATE,
      A~KEY_DATE AS KEY_OS_DATE,
      A~OD_DOC AS OS_BELNR,
      A~OD_YR AS OS_GJAHR,
      A~BLART ,
      A~OD_DATE AS OS_DATE,
      CASE WHEN A~SHKZG = 'H' THEN CAST( A~WRBTR * -1 AS CURR( 12, 2 ) ) 
           ELSE A~WRBTR 
      END AS OS_AMT ,
      A~DUE_DATE,
      A~ARREAR_DAYS,
      CASE WHEN A~ARREAR_DAYS <= 0 THEN 'NOD'
           WHEN A~ARREAR_DAYS > 0 THEN 'OD'
           ELSE ' '
      END AS OD_IND,
      A~HKONT,
      J~TXT50,
      A~PROD_CATEGORY,
      A~MATNR,
      K~MAKTX,
      A~WERKS ,
      L~NAME1,
      A~BWTAR,
      A~PROFIT_CENTRE AS PRCTR,
      COALESCE( F~PD_RATE , 0 ) AS RATE,
      0 AS PD_AMT,
      CASE WHEN A~ARREAR_DAYS > 0 THEN
             CAST( 
               DIVISION( 
                 ( CAST( A~WRBTR * F~PD_RATE AS CURR( 15 ,2 ) ) ) ,
                 100 ,
                 3 ) 
               AS CURR( 15, 2 ) )
             * -1
           ELSE 
             DIVISION( 
               ( CAST( A~WRBTR * F~PD_RATE AS CURR( 15 , 2 ) ) ) , 
               100 ,
               3 ) 
      END AS ITEM_PD_AMT,  "DISCOUNT_RATE,
      0 AS ITEM_PD_AMT1,
      A~MAIN_TYPE

      WHERE A~KUNNR IN @KUNNR
        AND NOT EXISTS (
            SELECT * 
            FROM ZFI_PAYMENT_DISC 
            WHERE BELNR = A~BELNR
              AND GJAHR = A~GJAHR 
              AND BUKRS = A~RBUKRS 
              AND SALES_OFFICE = @VKBUR-LOW 
              AND A~KUNNR IN @KUNNR 
              AND OS_BELNR EQ A~OD_DOC )
        AND A~ARREAR_DAYS <= @OD
        AND ( F~COL_AMT_FROM LE ( 
            SELECT SUM( COLLECT ) 
            FROM ZPD_HSL( BUKRS     = @BUKRS-LOW ,
                          BUDATFROM = @COL_DATE-LOW ,
                          BUDATO    = @COL_DATE-HIGH ) 
            WHERE KUNNR = A~KUNNR )
        AND F~COL_AMT_TO GE ( 
            SELECT SUM( COLLECT ) 
            FROM ZPD_HSL( BUKRS     = @BUKRS-LOW ,
                          BUDATFROM = @COL_DATE-LOW ,
                          BUDATO    = @COL_DATE-HIGH ) 
            WHERE KUNNR = A~KUNNR )
      )
    
      ORDER BY A~KUNNR, A~BELNR ,A~DUE_DATE ASCENDING
    
      INTO TABLE @PROV_POST.

This is a mere guess, as your complex setup makes it hard to reproduce a working example.

My assumption is that the INNER JOIN TVKBT AS I ON I~VKBUR = F~SALES_OFFICE is getting in the way. It inner-joins to your custom table, aliased as F , and might lead to an overreduction of records if the join order is interpreted wrong.

I'd recommend to remove that join and see whether that fixes the basic join result.

In any way, I would recommend to add parentheses and reorder the join clauses to make clear what the "left" side of the equation is, and to remove any ambiguity, both for the interpreter, and the reader.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM