긴 SQL구문을 쉽게 이해할 순 없을까?

Sibeet·2020년 6월 4일
0
post-thumbnail

TPC-H-SF1의 2번 쿼리를 살펴보자.

  SELECT
      S_ACCTBAL,
      S_NAME,
      N_NAME,
      P_PARTKEY,
      P_MFGR,
      S_ADDRESS,
      S_PHONE,
      S_COMMENT
  FROM
      PART,
      SUPPLIER,
      PARTSUPP,
      NATION,
      REGION
  WHERE
        P_PARTKEY = PS_PARTKEY
    AND S_SUPPKEY = PS_SUPPKEY
    AND P_SIZE = 15
    AND P_TYPE LIKE '%BRASS'
    AND S_NATIONKEY = N_NATIONKEY
    AND N_REGIONKEY = R_REGIONKEY
    AND R_NAME = 'EUROPE'
    AND PS_SUPPLYCOST = (
                           SELECT
                                  MIN(PS_SUPPLYCOST)
                           FROM
                                  PARTSUPP, SUPPLIER,
                                  NATION, REGION
                           WHERE
                                  P_PARTKEY = PS_PARTKEY
                              AND S_SUPPKEY = PS_SUPPKEY
                              AND S_NATIONKEY = N_NATIONKEY
                              AND N_REGIONKEY = R_REGIONKEY
                              AND R_NAME = 'EUROPE'
                        )
  ORDER BY
      S_ACCTBAL DESC,
      N_NAME,
      S_NAME,
      P_PARTKEY
  FETCH 100;

🙁...🤔...뭔 소리야?

쿼리는 길고, 서브쿼리도 있고, 조건도 많고, 조인조건도 많다.
이 정도 쿼리면 정리라도 잘해놨다. 현실은 PART가 아니고 IM_PT, SUPPLIER가 아니고 IM_SUP로 작명해놓은 경우가 압도적으로 더 많다.

대체 무슨 소리인지 알 수가 없어...

내가 짠 쿼리면 이해라도 하지, 남이 짠 쿼리에 Column은 IM_SUP이면 대체 뭔 소리야? 이 생각부터 드는게 인지상정이다. 아니면 그게 이상한 거다.

이럴 때 사용하는 아주 유용한 방법이 하나 있다. 애초에 쿼리란 건 Relation 모델을 언어로 옮겨 놓은 것이다. 그럼 관계도를 보면 파악할 수 있지 않을까?

🙄?

그런 발상으로 그림을 그려 보면 어떨지 보자.

일단 암거나 한번 찾아 보자. 흠... 일단은 where 조건이 존재하는 놈 아무거나 찾아야겠군. P_SIZE, P_TYPE이 둘다 있는 PART부터 시작해봐야지.

PART, 그러니까 부품의 크기가 15이고, 부품의 종류가 BRASS, 황동인 케이스이다. 좋아..여기까진 쉽다. 😋

그럼 이제 얘랑 관련있는 테이블을 찾아보면..partkey와 연관된 애를 찾으면 되겠네.

  FROM
      PART,
      PARTSUPP,
  WHERE
      P_PARTKEY = PS_PARTKEY

눈씻고 찾아봐도 PARTKEY와 관련된 애는 없고, 이거만 있다.

그럼 이제 그림을 다시 그려야지~

PARTSUPP에 연결된 테이블을 찾으면

FROM
      SUPPLIER,
      PARTSUPP,
WHERE
      S_SUPPKEY = PS_SUPPKEY

이런식으로 쭉쭉쭉 다 그려보면...🤭

대충 이렇게 된다.

subquery from절에 표기되지 않은 것은 상위 쿼리에서 table 조건을 가져온다는 걸 까먹지 말자. part가 없지만 p_partkey 조건이 있기 때문에 상위 part 조건을 다 가져온다.

흠....🤔 이제 그린 그림을 토대로 한번 이해해 보자.
일단 서브쿼리부터!

왼쪽부터 순서대로 시계방향으로 돌아보자면
1. PART의 SIZE가 15, TYPE은 BRASS
2. REGION의 NAME은 EUROPE
3. 그 조건 하에서 PARTSUPP의 SUPPLYCOST 중에서 최소값을 출력

한국말로 번역해보면, 유럽에 공급하는 부품 중에서 크기가 15이고 종류가 황동인 부품 중에 가장 작은 공급비용을 가지는 부품의 공급비용을 출력하는 쿼리가 서브쿼리다.

상위 쿼리로 올라가 해석해보면,
1. PART의 SIZE가 15, TYPE은 BRASS
2. REGION의 NAME은 EUROPE
3. PARTSUPP의 SUPPLYCOST가 MIN값
인 ROW의

  SELECT
      S_ACCTBAL,
      S_NAME,
      N_NAME,
      P_PARTKEY,
      P_MFGR,
      S_ADDRESS,
      S_PHONE,
      S_COMMENT

해당 정보들을 출력하는 쿼리가 된다. 😆

쓰고보니 예시가 좀 쉬운 예시였다는 생각이 드는데, 어쨌든 relation diagram을 통해서 쿼리의 전체적인 흐름을 파악할 수 있고, 이렇게 관계도를 그려놓으면 설령 해당 table이 무엇을 뜻하는지, 해당 column이 무엇을 뜻하는지를 몰라도 대략적인 흐름을 파악할 수 있다. 그러고 나서 해당 table과 column의 상세한 내용을 알면 되기 때문이다.

RDB는 Relation Database이다. 많은 것을 관계로 설명할 수 있다.

어때요, 참 쉽죠?

0개의 댓글