brunch

You can make anything
by writing

C.S.Lewis

by 데이터리안 Mar 28. 2023

SQL 가독성을 높이는 다섯 가지 사소한 습관

지독하게 읽기 힘든 SQL 쿼리를 해석해 본 적 있으신가요?

Q. SQL 설치 없이 코드를 실행해 볼 방법은 없을까요?
아래 코드는 모두 solvesql.com 의 플레이그라운드에서 실행하실 수 있습니다. 로그인 후 플레이그라운드 및 일부 SQL 연습문제를 무료로 사용하실 수 있습니다.


안녕하세요. 데이터리안의 윤선미입니다.

지독하게 읽기 힘든 SQL문을 해석해 본 적 있으신가요? 마치 암호를 읽는 것처럼 어렵죠. 꼭 남이 작성한 SQL이 아니더라도, 과거의 내가 작성한 SQL이 현재의 내 발목을 붙잡는 경우도 있습니다. 아무리 읽어도 도대체 뭘 의도하고 쓴 건지 모르겠죠... 내가 한 거라서 누굴 욕할 수도 없고요.


SQL은 띄어쓰기, 들여쓰기에 거의 규칙이 없다시피 한 언어입니다. 아래 두 코드 블럭은 같은 결과를 계산하는 코드입니다.


SELECT day, total_bill
FROM tips
SELECT day, total_bill FROM tips


파이썬 같이 들여쓰기, 띄어쓰기를 문법적으로 강제하는 언어를 써보신 분들이라면 SQL의 자유로움에 잠깐 해방감을 느낄지도 모르겠지만 곧 남이 써 놓은 SQL 문을 해독하면서 생각하겠지요. '뭐 이딴 언어가 다 있나...'

이번 글에서는 SQL 문법에서는 강제하지 않지만, 가독성 있는 SQL 코드를 쓸 수 있는 다섯 가지 습관을 얘기해볼게요.



1. 예약어는 대문자로

첫 번째는 SELECT, FROM, GROUP BY, HAVING, AS, AND와 같은 SQL 예약어들을 대문자로 쓰는 습관입니다. 아래 두 코드 중 어떤 코드가 더 잘 읽히나요? 저는 첫 번째 코드가 더 잘 읽힙니다.


SELECT tip, total_bill
FROM tips
select tip, total_bill
from tips


SQL 언어를 지원하는 에디터를 쓴다면 예약어들을 컬럼이나 테이블 이름과는 다른 색으로 하이라이팅을 해주기 때문에 굳이 대문자로 쓰지 않아도 잘 보이긴 합니다.

하지만 에디터마다 하이라이팅 규칙이 다르고 DB 종류마다 함수들 이름도 약간씩 다르기 때문에 함수(특히 

DATE_ADD() 같은 날짜 함수는 DB마다 차이가 크게 납니다)는 하이라이팅이 제대로 되지 않는 경우도 많습니다. 그래서 예약어, 함수 이름 등은 대문자로 써주는 습관을 가지면 좋아요.



2. 행갈이를 자주 하자

두 번째, 행갈이를 자주 하는 습관입니다. 아래 두 코드 중 어떤 코드가 더 잘 읽히나요? 역시 첫 번째 코드가 더 잘 읽힙니다.


SELECT day
           , time
           , SUM(total_bill)
FROM tips
GROUP BY day, time        
SELECT day, time, SUM(total_bill)
FROM tips
GROUP BY day, time


저는 행갈이를 자주 합니다. SELECT, FROM, GROUP BY와 같이 다른 절이 한 라인에 있는 코드를 작성하지 않습니다. 한 라인에 코드를 쭉 쓰면 그 의미를 파악하기 위해서 모든 코드를 다 읽어봐야 합니다. 두 번째 블럭의 경우 모든 코드를 끝까지 다 읽어야 '아 이게 집계를 하는 코드구나' 하고 알 수 있죠. 하지만 첫 번째 코드는 각 라인의 첫 번째 예약어들만 눈으로 쓱 훑어도 작성자의 의도와 코드의 구조를 파악할 수 있습니다.



3. 행갈이를 더 자주 하자

세 번째, 행갈이를 더! 자주 하는 습관입니다. 아래 두 코드 중 어떤 코드가 더 잘 읽히나요? 이번에는 비슷해 보입니다(?)

SELECT day
           , time
          , SUM(total_bill)
 FROM tips
WHERE sex = 'Female'
    AND smoker = 'Yes'
GROUP BY day
               , time        
SELECT day, time, SUM(total_bill)
FROM tips
WHERE sex = 'Female'
    AND smoker = 'Yes'
GROUP BY day, time 


첫 번째처럼 코드를 작성하는 것은 주석처리를 할 때 진가를 발휘하는데요. 예를 들어, 지금은 day, time 두 컬럼을 집계의 기준으로 사용하고 있는데 이 중에 day만 남기고 싶다고 생각해볼게요. 그럴 때 이렇게 라인을 주석처리 하는 방식으로 time 컬럼을 로직에서 제외할 수 있습니다.   

      

SELECT day
        -- , time
           , SUM(total_bill)
FROM tips
WHERE sex = 'Female'
     AND smoker = 'Yes'
GROUP BY day
            -- , time 


가끔 쿼리를 쓸 때, 이렇게 어떤 로직을 제외했다가 포함시켰다가 해야 할 일이 생기잖아요. (저만 그런 건 아닐 거라고 생각합니다...) 그럴 때 행갈이를 더! 자주 하는 습관이 빛을 발합니다. WHERE 절에서도 AND, OR가 붙을 때마다 행갈이를 해주면 아래와 같이 활용할 수 있습니다.


SELECT day
           , time
          , SUM(total_bill)
FROM tips
WHERE 1 = 1
 -- AND sex = 'Female'
    AND smoker = 'Yes'
GROUP BY day
               , time


어떤 분들은 위와 같이 WHERE 절이 시작하자마자 1 = 1 이라는 아무 의미 없는 조건을 넣어주고 행갈이를 한 다음 AND로 진짜 필터링 조건을 쓰기 시작하시는 분들도 있더라구요. 저는 저렇게까지 쓰지는 않는데, 재미있는 응용인 것 같아서 적어봤습니다.



4. 주석을 쓰자

네 번째, 코드를 쓴 의도를 짤막하게라도 적어놓는 습관을 들이는 게 좋습니다. (물론 저도 들이지 못했습니다.) 특히 서브쿼리가 많아지고 코드가 길어질수록 각 코드 단락이 어떤 의도로 작성되었는지 디테일을 적어놓아야 다음에 그 코드를 읽었을 때 이해할 수 있습니다.


SELECT AVG(sales) avg_sales
FROM (
    -- 요일별 매출액 합계 계산
    SELECT day -- 일별 X 요일별 O
              , SUM(total_bill) sales
    FROM tips
    WHERE sex = 'Female' -- 결제자의 성별이 여성인 경우
    GROUP BY day
) daily_sales


주석은 서브쿼리 단위로 쓸 수도 있고, CASE, IF 조건문 또는 WHERE 절 필터링 조건을 쓸 때도 적어주는 것이 좋습니다.


이런 것들을 주석에 적어주면 좋아요.

서브쿼리의 단위로 의미를 적어주세요.

조건에 적은 주석의 경우, 단순히 '이 조건은 이거다'(What)라고 서술하는 건 별로 의미가 없습니다. 그러나 컬럼 이름만 보고 해석에 오해가 있을 수 있거나, 추가 설명이 필요한 경우에는 적어주는 것이 좋습니다.

조건이 왜 필요한지(Why), 어떻게 동작하는지(How) 같은 디테일을 적어놓으면 추후에 코드를 이해하는 데 도움을 줍니다.  



5. Alias를 잘 쓰자

주석을 잘 적어놓는 것도 중요하지만, 결국 코드를 잘 써야 전체를 빠르게 이해할 수 있습니다. 혹시 서브쿼리, 컬럼 Alias 를 'x', 'y', 't', 'df', 'a' 등으로 대충 쓰고 계시지는 않나요?

FROM 절 서브쿼리 이름을 't1' 이라고 지어놨다가 아우터 쿼리 저어어어기 어딘가에서 t1.x + t2.y 라는 코드를 발견했다고 칩시다. 그 코드가 어떤 동작을 하는지 알려면 저 Alias를 쓴 서브쿼리까지 결국 다시 찾아가야 합니다. 네네, 압니다. 데이터 분석용으로 쓰는 쿼리는 재활용할 일이 많지도 않은데, 다른 프로그래밍 언어 코딩하듯이 작명의 고통을 받아 가면서 그 많은 Alias 작명을 해야겠냐는 아우성... 여기까지 들립니다. 그리고 그 아우성은 제 안의 아우성이기도 한데요. 그러면 어쩔 수 없죠. 다음에 그 코드 다시 볼 일이 생기면 고통받는 수밖에요.

희소식은, 이런 고민을 우리만 하고 있는게 아니란 겁니다. 구글에 '변수명 짓기 팁'을 검색하면 수많은 선배 작명가들이 변수명을 잘 짓기 위한 팁들을 알려주고 있습니다. 그리고 또 한가지 희소식은... 이름 짓는 것도 하다 보면 늡니다. 적어도 't', 't1', 'df', 'a', 'x' 같은 Alias는 쓰지 맙시다.



마치며

여러 규칙에 대해서 얘기했지만, 가장 중요한 것은 내가 같이 일하는 사람들과 합의된 규칙입니다. 아무리 좋은 방법이라도 팀에서 사용하고 있는 컨벤션에 위배된다면, 기존 구성원들을 설득하고 레거시 코드들을 죄다 바꾸는 수고를 하지 않는 한 일단 기존 제도를 따라야 한다고 생각합니다. 아무리 좋은 변수명 짓기 규칙이 있다고 하더라도 기존에 있는 코드 규칙을 완전히 무시하고 나만 "무소의 뿔처럼 혼자서" 갈 수는 없는 법입니다.

그리고 무엇보다 이 코드를 나 말고 누군가가 볼 거라고 생각하면서 작성하고 정리하는 것이 중요합니다. (엉망진창인 전임자의 SQL 코드를 보면서 열받았던 경험이 있는 것이 절대 아닙니다.) 사람 일은 모르는 것입니다. 지금 잘 작성한 SQL 코드 한 단락이 미래의 나를 구하게 될지도 모르지요.

SQL 코드 가독성을 높이는 사소하지만 중요한 다섯 가지 습관에 관해서 얘기해봤습니다. 여러분들도 혹시 여러분들만의 노하우를 가지고 계신가요? SQL 코드 작성에 대한 꿀팁이 넘치는 데이터리안의 SQL 데이터 분석 캠프에도 많은 관심 부탁드립니다.





더 많은 데이터리안의 글을 읽어보고 싶다면,



SQL로 퍼널 분석을 어떻게 하는지 궁금하다면?

RFM 고객 세분화 분석, 매출 분석, 코호트, 리텐션 분석, 퍼널 분석 등 실무에서 자주 쓰이는 분석 프레임워크를 한번에 배울 수 있는 SQL 데이터 분석 캠프 커리큘럼을 확인해보세요.

매거진의 이전글 UA에서 GA4로 전환하기
브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari