ABAP Open SQL SELECT 문: JOIN 문 이용 두 테이블 함께 조회

ABAP Open SQL 도 다른 SQL 과 같이 JOIN 문을 제공 해 두 테이블을 함께 조회 할 수 있다. 오늘은 JOIN 의 기본적인 사용 법과 유형들을 정리 해보자.

JOIN 문의 기본 구조

SELECT [DISTINCT] <필드 리스트>
FROM <테이블1> [AS] <별칭1>
[INNER | LEFT OUTER | RIGHT OUTER] JOIN <테이블2> [AS] <별칭2>
ON <별칭1>.<필드명1> = <별칭2>.<필드명2>
[WHERE 조건]
[INTO <내부 테이블>]
[ORDER BY <필드명>].
ABAP
  • [INNER | LEFT OUTER | RIGHT OUTER] JOIN: 조인 유형으로 결과 값이 달라진다. 아래에서 상세하게 다룬다.
  • ON: ON 은 결합할 필드를 적는다. 대부분 두 테이블의 키 값을 서로 결합 하게 된다.
  • 필드 리스트 또한 “별칭.필드” 를 적어 어느 테이블의 필드의 값을 가져올 지 정한다. (한쪽에만 있는 필드는 별칭이 없어도 문제는 없다.)

INNER JOIN

두 테이블에서 ON 으로 결합한 필드의 값이 서로 일치하여 존재할 경우에만 결과가 출력 되는 코드다. 다음 SFLIGHT 와 SCARR 테이블은 각각 항공편, 항공사 이름을 지닌 테이블로 carrid(항공 ID) 의 KEY 필드를 둘 다 지니고 있다.

다음 코드를 통해 각 테이블 내역을 조회해 보자.

DATA: lt_table TYPE TABLE OF sflight,
      ls_table TYPE sflight.

SELECT a~carrid
       b~carrname
       a~connid
       a~fldate
INTO CORRESPONDING FIELDS OF TABLE lt_table
FROM sflight
WHERE carrid = 'TE'
   OR carrid = 'UA'
   OR carrid = 'SQ'.

WRITE: /(20)'carrid',
        (20)'connid',
        (20)'fldate'.

LOOP AT lt_table INTO ls_table.
  WRITE: / ls_table-carrid UNDER 'carrid',
           ls_table-connid UNDER 'connid',
           ls_table-fldate UNDER 'fldate'.
ENDLOOP.
ABAP
SFLIGHT 테이블 조회 결과
DATA: lt_scarr TYPE TABLE OF scarr,
      ls_scarr TYPE scarr.

SELECT *
INTO CORRESPONDING FIELDS OF TABLE lt_scarr
FROM scarr.

WRITE: /(20)'carrid',
        (20)'carrname'.

LOOP AT lt_scarr INTO ls_scarr.
  WRITE: / ls_scarr-carrid   UNDER 'carrid',
           ls_scarr-carrname UNDER'carrname'.
ENDLOOP.
ABAP
SCARR 테이블 조회 결과
SCARR 테이블 조회 결과

이렇게 두 테이블의 결과 값이 있을 때, SFLIGHT 의 결과에 SCARR 테이블의 항공사 이름(carrname) 를 붙여 출력하고 싶다면 JOIN 을 이용할 수 있는 것이다.

그럼 INNER JOIN 을 이용해서 한번 두 테이블을 결합해 보자.

TYPES: BEGIN OF ty_table,
         carrid   TYPE sflight-carrid,
         carrname TYPE scarr-carrname,
         connid   TYPE sflight-connid,
         fldate   TYPE sflight-fldate,
       END OF ty_table.

DATA: lt_table TYPE TABLE OF ty_table,
      ls_table TYPE ty_table.

SELECT *
INTO CORRESPONDING FIELDS OF TABLE lt_table
FROM sflight AS a INNER JOIN scarr AS b
  ON a~carrid EQ b~carrid
WHERE a~carrid = 'TE'
   OR a~carrid = 'UA'
   OR a~carrid = 'SQ'.

WRITE: /(20)'carrid',
        (20)'carrname',
        (20)'connid',
        (20)'fldate'.

LOOP AT lt_table INTO ls_table.
  WRITE: / ls_table-carrid   UNDER 'carrid',
           ls_table-carrname UNDER 'carrname',
           ls_table-connid   UNDER 'connid',
           ls_table-fldate   UNDER 'fldate'.
ENDLOOP.
ABAP
INNER JOIN 테이블 조회 결과
INNER JOIN 테이블 조회 결과

위의 코드를 보면 두 테이블의 별칭을 각각 a, b 로 정해 준 후 inner join 으로 결합하였다.

결합 할 기준 값은 같은 carrid ID 를 지닌 값으로 INTO CORRESPONDING FIELDS OF TABLE 로 Internal Table 인 lt_table 에 값이 잘 들어간 것을 알 수 있다.

그런데 보면, 위의 설명과 같이 ‘서로 일치 하는 값이 존재하는 경우’ 에만 출력 되는 INNER JOIN 의 특징으로 인해 sflight 에 carrid 가 ‘TE’ 인 행들이 출력 되지 않는다.

이런 경우 표시하고 싶다면 아래 LEFT OUTER JOIN 을 사용할 수 있다.

LEFT OUTER JOIN

LEFT OUTER JOIN 은 왼쪽의 테이블이 기준 테이블이 되고 조인한 테이블 에서 일치하는 내용을 읽어와 추가로 표시할 때 사용한다.

위의 INNER JOIN 에서 sflight 와 scarr 테이블을 조합 했을 때 ON 으로 조합한 필드의 값이 서로 동일한 게 존재 할 경우 행이 조회 되었지만, LEFT OUTER JOIN 은 sflight 의 값을 먼저 다 가져온 후, 일치하는 경우에만 추가로 scarr 을 표시 한다.

그래서 scarr 테이블에 없는 carrid 인 TE 값을 지닌 행들도 전부 출력 된다.

추가로, LEFT OUTER JOIN 에서는 기준 점이 된 sflight 테이블에만 where 조건을 넣을 수 있고 scarr은 불가능 하다.

TYPES: BEGIN OF ty_table,
         carrid   TYPE sflight-carrid,
         carrname TYPE scarr-carrname,
         connid   TYPE sflight-connid,
         fldate   TYPE sflight-fldate,
       END OF ty_table.

DATA: lt_table TYPE TABLE OF ty_table,
      ls_table TYPE ty_table.

SELECT a~carrid
       b~carrname 
       a~connid
       a~fldate
INTO CORRESPONDING FIELDS OF TABLE lt_table
FROM sflight AS a LEFT OUTER JOIN scarr AS b
  ON a~carrid EQ b~carrid
WHERE a~carrid = 'TE'
   OR a~carrid = 'UA'
   OR a~carrid = 'SQ'.

WRITE: /(20)'carrid',
        (20)'carrname',
        (20)'connid',
        (20)'fldate'.

LOOP AT lt_table INTO ls_table.
  WRITE: / ls_table-carrid   UNDER 'carrid',
           ls_table-carrname UNDER 'carrname',
           ls_table-connid   UNDER 'connid',
           ls_table-fldate   UNDER 'fldate'.
ENDLOOP.
ABAP
LEFT OUTER JOIN 테이블 조회 결과
LEFT OUTER JOIN 테이블 조회 결과

TE 는 carrname 이 scarr 테이블에 없으니까 공백으로 표시 되지만, INNER JOIN 과 다르게 행 자체는 조회가 된다.

RIGHT OUTER JOIN

LEFT OUTER JOIN 에선 왼쪽 테이블을 중심으로 값을 조회 했다면, RIGHT OUTER JOIN 은 우측에 온 테이블을 중심으로 값을 조회 하는 것이다. 그래서 위의 코드를 RIGHT OUTER JOIN 으로 변경 해 주면 이번엔 TE 값이 scarr 에 없으므로 출력 되지 않는다.

그런데, 이 코드를 활성화 하면서 특이한 점을 발견 했다. LEFT 를 RIGHT 로 바꾸니 필드를 쉼표(,) 로 구분하고 Internal Table 앞에 @를 붙이라는 오류 메시지가 출력된다.

@이는 7.40 버전 이상의 ABAP 에서 도입 되었으며 ABAP 내 선언 된 변수임을 표기하는 의미라고 한다. 그런데 왜 RIGHT OUTER JOIN 에서만 이런 현상이 발견 되는지는 알 수 없었다. 어쨌든, 오류 메시지를 해결하여 코드를 작성하면 다음과 같다.

TYPES: BEGIN OF ty_table,
         carrid   TYPE sflight-carrid,
         carrname TYPE scarr-carrname,
         connid   TYPE sflight-connid,
         fldate   TYPE sflight-fldate,
       END OF ty_table.

DATA: lt_table TYPE TABLE OF ty_table,
      ls_table TYPE ty_table.

SELECT b~carrid,
       b~carrname,
       a~connid,
       a~fldate
INTO CORRESPONDING FIELDS OF TABLE @lt_table
FROM sflight AS a RIGHT OUTER JOIN scarr AS b
  ON a~carrid = b~carrid
WHERE a~carrid = 'TE'
   OR a~carrid = 'UA'
   OR a~carrid = 'SQ'.

WRITE: /(20)'carrid',
        (20)'carrname',
        (20)'connid',
        (20)'fldate'.

LOOP AT lt_table INTO ls_table.
  WRITE: / ls_table-carrid   UNDER 'carrid',
           ls_table-carrname UNDER 'carrname',
           ls_table-connid   UNDER 'connid',
           ls_table-fldate   UNDER 'fldate'.
ENDLOOP.
ABAP
RIGHT OUTER JOIN 테이블 조회 결과
RIGHT OUTER JOIN 테이블 조회 결과
0 0 votes
Article Rating
Subscribe
Notify of
guest
0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x
목차
위로 스크롤