簡體   English   中英

如何用一個 ABAP SQL 語句連接以下 3 個表

[英]How to join the following 3 tables with exactly one ABAP SQL statement

我有以下 3 個包含數據的表:

ZMYTABLE與列: ZUSERZTCODE和2條記錄

elias  VA01  
elias  VF01

AGR_1251與記錄

SD_role  VA01  
SD2_role VA01  
SD3_role VA01  
SD_role  VA02  
FI_role  VF01  
FI_role  VF02

AGR_USERS有記錄

elias  SD_role  
elias  SD2_role   
maria  SD_role  
maria  FI_role

我想顯示字段ZUSERZTCODEAGR_NAME
我希望來自ZMYTABLE所有記錄ZMYTABLE具有特定用戶的每個 tcode 存在的角色,即:

ZUSER---ZTCODE---AGRNAME  
elias---VA01-----SD_role  
elias---VA01-----SD2_role  
elias---VF01-----        

有人能告訴我如何通過在 ABAP V7.01 sp07 中用一個 ABAP SQL 語句連接 3 個表來做到這一點嗎?

我發現使用UNION更容易,第一個 SELECT 將返回與匹配一個用戶角色(elias、VA01、SD_role 和 SD2_role)的事務對應的行,第二個將返回與事務對應的行與任何用戶角色(elias、VF01)都不匹配。

我通過用 USR07 替換 ZMYTABLE 來測試它。

    SELECT usr07~bname, usr07~tcode, agr_1251~agr_name
      FROM agr_users
      INNER JOIN usr07
        ON usr07~bname EQ agr_users~uname
      INNER JOIN agr_1251
        ON agr_1251~agr_name EQ agr_users~agr_name
           AND agr_1251~low  EQ usr07~tcode
    UNION
    SELECT DISTINCT usr07~bname, usr07~tcode, ' ' AS agr_name
      FROM usr07
      WHERE NOT EXISTS (
        SELECT * FROM agr_users
          INNER JOIN agr_1251
            ON agr_1251~agr_name EQ agr_users~agr_name
          WHERE usr07~bname  EQ agr_users~uname
            AND agr_1251~low EQ usr07~tcode )
    INTO TABLE @DATA(result).

它給出了這些結果(格式化為 ABAP 單元):

    SORT result BY bname tcode agr_name.
    TYPES ty_result LIKE result.
    assert_equals( act = result exp = VALUE ty_result(
      ( bname = 'elias' tcode = 'VA01' agr_name = 'SD2_role' )
      ( bname = 'elias' tcode = 'VA01' agr_name = 'SD_role'  )
      ( bname = 'elias' tcode = 'VF01' agr_name = ''         ) ) ).    

下面是 ABAP 單元測試代碼來演示它的工作原理,如果需要,您可以使用它。 您需要 ABAP 7.52(Open SQL Test Double Framework)。

CLASS ltc_main DEFINITION FOR TESTING DURATION SHORT RISK LEVEL HARMLESS
      INHERITING FROM cl_aunit_assert.
  PRIVATE SECTION.
    METHODS test FOR TESTING.
    CLASS-METHODS: class_setup, class_teardown.
    CLASS-DATA environment TYPE REF TO if_osql_test_environment.
ENDCLASS.
CLASS ltc_main IMPLEMENTATION.
  METHOD class_setup.
    environment = cl_osql_test_environment=>create( i_dependency_list = VALUE #( 
          ( 'USR07' ) ( 'AGR_1251' ) ( 'AGR_USERS' ) ) ).
  ENDMETHOD.
  METHOD test.
    TYPES ty_usr07 TYPE STANDARD TABLE OF usr07 WITH EMPTY KEY.
    TYPES ty_agr_1251 TYPE STANDARD TABLE OF agr_1251 WITH EMPTY KEY.
    TYPES ty_agr_users TYPE STANDARD TABLE OF agr_users WITH EMPTY KEY.

    environment->insert_test_data( EXPORTING i_data = VALUE ty_usr07(
      ( bname = 'elias' tcode = 'VA01' timestamp = 1 )
      ( bname = 'elias' tcode = 'VF01' timestamp = 2 ) ) ).
    environment->insert_test_data( EXPORTING i_data = VALUE ty_agr_1251(
      ( agr_name = 'SD_role'  low = 'VA01' counter = 1 )
      ( agr_name = 'SD2_role' low = 'VA01' counter = 1 )
      ( agr_name = 'SD3_role' low = 'VA01' counter = 1 )
      ( agr_name = 'SD_role ' low = 'VA02' counter = 2 )
      ( agr_name = 'FI_role ' low = 'VF01' counter = 1 )
      ( agr_name = 'FI_role ' low = 'VF02' counter = 2 ) ) ).
    environment->insert_test_data( EXPORTING i_data = VALUE ty_agr_users(
      ( uname = 'elias' agr_name = 'SD_role ' )
      ( uname = 'elias' agr_name = 'SD2_role' )
      ( uname = 'maria' agr_name = 'SD_role ' )
      ( uname = 'maria' agr_name = 'FI_role ' ) ) ).

    "<==== here insert the ABAP SQL provided above & expectations to verify

    ROLLBACK WORK.

  ENDMETHOD.

  METHOD class_teardown.
    environment->destroy( ).
  ENDMETHOD.

ENDCLASS.

如果您的 ABAP 版本 < 7.50,則UNION是不可能的,而是定義 2 個單獨的SELECT ,第一個帶有INTO TABLE @DATA(result) ,第二個帶有APPENDING TABLE result


PS:我還進行了以下測試,受到其他答案的啟發,它們不起作用(其中大多數為“VF01”返回角色“FI_role”,而不是空角色)。

失敗的嘗試 1-A:

     SELECT usr07~bname, usr07~tcode, agr_1251~agr_name
       FROM agr_users
       INNER JOIN usr07
         ON usr07~bname EQ agr_users~uname
       INNER JOIN agr_1251
         ON agr_1251~agr_name EQ agr_users~agr_name AND
            agr_1251~low      EQ usr07~tcode
       INTO TABLE @DATA(result).
    SORT result BY bname tcode agr_name.
    TYPES ty_result LIKE result.
    assert_equals( act = result exp = VALUE ty_result(
      ( bname = 'elias' tcode = 'VA01' agr_name = 'SD2_role' )
      ( bname = 'elias' tcode = 'VA01' agr_name = 'SD_role' ) ) ).

失敗的嘗試 1-B:

     SELECT DISTINCT usr07~bname,
                 usr07~tcode,
                 agr_1251~agr_name
           FROM usr07
           INNER JOIN agr_1251
             ON agr_1251~low EQ usr07~tcode
           INNER JOIN agr_users
             ON agr_users~uname EQ usr07~bname
           WHERE
              agr_users~agr_name EQ agr_1251~agr_name OR EXISTS (
              SELECT *
              FROM agr_users AS inner_agr_users
              INNER JOIN agr_1251 AS inner_agr_1251
                ON inner_agr_1251~agr_name EQ inner_agr_users~agr_name
              WHERE
                inner_agr_users~agr_name EQ agr_1251~agr_name
           )
           INTO TABLE @DATA(result).
    SORT result BY bname tcode agr_name.
    TYPES ty_result LIKE result.
    assert_equals( act = result exp = VALUE ty_result(
      ( bname = 'elias' tcode = 'VA01' agr_name = 'SD2_role' )
      ( bname = 'elias' tcode = 'VA01' agr_name = 'SD_role' )
      ( bname = 'elias' tcode = 'VF01' agr_name = 'FI_role' ) ) ).

失敗的嘗試 2:

     SELECT b~bname, b~tcode, a~agr_name
       FROM agr_1251 as a
       INNER JOIN usr07 as b
         ON a~low EQ b~tcode
       INNER JOIN agr_users as c
         ON a~agr_name EQ c~agr_name
       INTO TABLE @DATA(result).
    SORT result BY bname tcode agr_name.
    TYPES ty_result LIKE result.
    assert_equals( act = result exp = VALUE ty_result(
      ( bname = 'elias' tcode = 'VA01' agr_name = 'SD2_role' )
      ( bname = 'elias' tcode = 'VA01' agr_name = 'SD_role' )
      ( bname = 'elias' tcode = 'VA01' agr_name = 'SD_role' )
      ( bname = 'elias' tcode = 'VF01' agr_name = 'FI_role' ) ) ).

數據庫訪問應如下所示:

SELECT DISTINCT zmytable~zuser,
                zmytable~ztcode,
                agr_1251~agr_name
FROM zmytable
INNER JOIN agr_1251
  ON agr_1251.ztcode EQ zmytable.ztcode
INNER JOIN agr_users
  ON agr_users.zuser EQ zmytable.zuser
WHERE
   agr_users.agr_name EQ agr_1251.agr_name OR EXISTS(
   SELECT *
   FROM agr_users AS inner_agr_users
   INNER JOIN agr_1251 AS inner_agr_1251
     ON inner_agr_1251.agr_name EQ inner_agr_users.agr_name
   WHERE
     inner_agr_users.agr_name EQ agr_1251.agr_name
).

添加INTO子句並處理輸出。

  • 我打算在有時間的時候用解釋來升級答案。

要訪問所有記錄,您應該使用 DB Access,如下所示。

SELECT b~zuser, b~ztcode, a~agr_name
  FROM agr_1251 as a
  INNER JOIN zmytable as b
    ON a~tcode EQ b~tcode
  INNER JOIN agr_user as c
    ON a~agr_name EQ c~agr_name.

休息一下,您可以使用 ABAP 來顯示輸出。

Triple Join適用於版本 > 7.4。

SELECT c~zuser, a~zrole, c~ztcode INTO CORRESPONDING FIELDS OF TABLE @lt_result
     FROM agr_users AS a INNER JOIN agr_1251 AS b 
         ON a~zrole = b~zrole
            RIGHT OUTER JOIN zmytable AS c 
              ON c~ztcode = b~ztcode AND c~zuser = a~zuser.

我一直在尋找SU53報告內容存儲在哪個表中。 似乎它存儲在USR07和USR07_EXT中以獲取更高版本。

這就是我到達這篇文章的方式。

但是,該表始終為空,盡管對於其他用戶ID和我的用戶ID顯然有SU53內容。

在這里真的很傷人,因為如果您在SU53報告中單擊F1然后單擊扳手圖標,它將指向表USR07,該表為空。

我想念什么? 謝謝

哦,順便說一句,我正在尋找一個表,該表保留每個用戶的最后一次身份驗證檢查失敗。 我們希望使用此信息,以便聊天機器人可以獲取此信息並與UST12以及最終與原始單個角色進行交叉引用。 我們有一個設置,其中每個auth-object-field-value組合都恰好包含1個單一角色。 否則,聊天機器人將必須向最終用戶提供多個單個角色匹配的列表,我們知道最終用戶將選擇該角色。 因此,只有1個匹配項,聊天機器人就可以代表該用戶來完成請求任務的單一角色。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM