인턴을 하면서 느낀점은
프로그램의 성능 최적화는 DB에서 Select 하는 과정을 어떻게 하는지가 중요한거 같다.
일반적으로 Service에서 값을 원하는 형태로 변형하여 넘겨도 되지만
쿼리로 제작할 수 있다면 제일 베스트이다.
여기서 가장 중요한건 서브쿼리, 내장함수도 중요하지만
기본적인 Group by와 Order By의 중요성이다.
우선 이론적인 학습을 해보자.
1. GROUP BY
그룹이라는 말 처럼 AVG, SUM과 같이 전체 값을 연산했을 때 주로 사용되는데
일반적으로 여러개의 행을 이용하여 통계적인 값을 추출할 수 있다.
2. ORDER BY
ORDER BY는 조회하려는 데이터를 정렬로 자주 사용되곤 한다.
일반적으로 쿼리를 제작하다보면 Group by 형식 오류를 자주 접하는 사람들이 있다.
이 경우에는 Select에 지정한 컬럼을 모두 포함했는지 확인해야 한다.
최근에 동료 인턴의 쿼리를 도와주면서 아쉬웠던 부분이 바로 이 문제였다.
예를 들어보면
SELECT A~~~~
FROM(
SELECT B~~~~~
FROM
)
GROUP BY C~~~
위와 같다고 가정했을 때
우선 서브쿼리에 대한 별칭을 A부분에서 사용가능하다는 것을 알 수 있는데
해당 SELECT에 뽑으려는 모든 데이터를 C에 같이 나열해줘야 한다.
서브쿼리를 이용하다보면 오류가 어디서 발생했는지 확인하기 어려운데
이럴땐 스크립트로 돌려보면서 오류를 찾으면 된다.
추가적으로 오라클을 이용하면서 TO_DATE와 TO_CHAR를 자주 사용하는데
혹시 날짜값을 TO_CHAR를 이용할 때 1~7까지의 숫자로 반환된다는 것을 알고 있는가?
날짜값을 TO_CHAR로 할 경우 숫자로 반환되고 이를 이용하여 결과를 도출할 수 있다.
나중에 기회가 된다면 한번 이용해보는걸 추천하며
오늘 팀 프로젝트에서 해당 월에 대한 첫번째 날부터 마지막 날을 구하는 쿼리를 작성했다.
select
TO_CHAR(LAST_DAY('20200901')),
ADD_MONTHS(FRISTDAYS, -1) AS 첫번째날
,TO_CHAR(LAST_DAY('20200901') - LASTDAYS) AS 마지막날
FROM (
SELECT TO_CHAR(LAST_DAY('20200901'), 'DD') AS LASTDAYS
,TO_CHAR(TRUNC(TO_DATE('20200901'), 'MM')) AS FRISTDAYS
FROM DUAL
);
원래는 SYSDATE를 이용하여 구현하고 현재 사용중인데
위의 쿼리는 내가 끄적인 테스트 쿼리다.
아마 위의 쿼리를 돌리면 31, 2020/08/01, 2020/08/31 이라는 값을 확인할 수 있다.
여기서 포인트는 LAST_DAY, TRUNC이다.
LAST_DAY는 해당 년월일에 대한 마지막 일을 출력해준다.
TRUNC는 다양한 용도로 사용되는데 절사로 이용하여 연도로 이용할 땐 1일에 대한 값을 도출하기 위해 사용한다.
무튼 LAST_DAY와 TRUNC를 이용하면 도움이 된다.
마지막으로는 WITH AS를 이용하는 것이다.
WITH AS를 이용한다고 하면 당황스러울 것이다.
사실 WITH AS로 만들게 되면 자칫 쿼리도 길어지고 양이 많아지게 되는데
세기무민(가장 일 처리를 많이 한 직원) | 80.9% |
세무민쓰(가장 업무 대비 성과가 좋은 직원) | 77.4% |
예를 들어서 위의 표처럼 값을 추린다고 가정해보자.
이럴 때 어떻게 표현할 것인가?
Service 로직에서 수정해도 무관하지만
With As와 Union을 이용한다면?
내가 원하는 값을 서브쿼리로 정리한 뒤 붙여주면 쉽게 끝난다.
with tmp1 as(
select A~~~~
from B~~~~
group by c~~~~
), tmp2 as(
select A2~~~~
from B2~~~~
group by c2~~~~
)
select * from tmp1
UNION all
select * from tmp2
실제로 사용하는 쿼리는 보안상 이용할 수 없어서 예시를 표현해봤다.
실제 원하는 값을 추출하기 위해서는 값을 union을 이용해서 붙여주는 것도 하나의 방법이다.
실제 사용했을 땐 max값을 이용할 때 group by를 이용하지 않고
over(PARTITION BY ~)를 이용하여 간편하게 구현했다.
무튼 위에 경우를 말한 이유는 동료 인턴의 쿼리를 도와주다가
위에처럼 원하는 값을 어떻게 해야할 지 모르길레 위와 같은 방법으로 붙여보라고 추천했고
실제 그렇게 진행했다.
사실 위에 경우가 무조건 맞다고는 할 수 없다.
그렇지만 위의 경우처럼 용어들을 알아 두신다면
나중에 오라클을 이용하면서 도움이 되지 않을까 싶어서 작성해봤습니다.
사실 실제 쿼리를 작성하지 않았지만 추후에 임의의 테이블을 만들어서 다시 포스팅 해보겠습니다.
다음에는 더 좋은 포스팅으로 찾아오겠습니다.
'DB > SQL' 카테고리의 다른 글
[세무민의 코딩일기] 쉬우면서 어려운 집계함수에 대해서 알아보자! (0) | 2021.07.22 |
---|---|
CRUD와 다양한 SELECT 검색조건에 대해서 자세하게 알아봅시다![DISTINCT, LIKE, IN, BETWEEN 등] (0) | 2021.07.21 |
세무민의 코딩일기 : CodeTable 혹은 ZTable에 대해서 알아봅시다. (0) | 2021.07.21 |
세무민의 코딩일기 : DB 함수 공부하기 (1) | 2021.04.18 |
Oracle DB로 달력 만들기! (8) | 2021.04.12 |