Oracle을 오래 써왔던 탓에 MariaDB로 뭘 하려고 하다보니까 문법의 차이나... 함수나... 적응이 쉽지는 않네요 ㅠㅠ
오늘은 MariaDB(+MySQL)에서 Outer join시 조건을 주는 법에 대한 포스팅을 준비했습니다.
MariaDB 역시 Outer Join에 대한 개념은 Oracle과 다르지 않습니다. 다만 개인적으로 자주 사용하던 (+) 연산자가 되지 않아서 불편하긴 하네요..
문제가 되는 쿼리 로그입니다.
(참고로 PM_CALENDAR 라는 테이블에는 날짜 데이터들이 들어있고, PM_COMMUTE 라는 테이블에는 유저마다 날짜에 해당하는 출,퇴근 시간이 찍힌 데이터가 들어있습니다)
원하는 결과는 B테이블(PM_COMMUTE)에 대한 Null 처리였는데 어째서인지 Inner Join과 같은 결과를 내뱉고 있었습니다.
SELECT
DISTINCT
B.CMPCD
, A.DATECHAR
, B.WORKDAY
, B.USERCD
, DATE_FORMAT(B.TODATE, '%H:%i') TODATE
, DATE_FORMAT(B.FROMDATE, '%H:%i') FROMDATE
FROM PM_CALENDAR A
LEFT OUTER JOIN PM_COMMUTE B
ON A.DATECHAR = B.WORKDAY
WHERE SUBSTRING(A.DATECHAR,1,6) = '202004'
AND B.CMPCD = 'P0001'
AND B.USERCD = 'admin'
조건을 없애보면.
SELECT
DISTINCT
B.CMPCD
, A.DATECHAR
, B.WORKDAY
, B.USERCD
, DATE_FORMAT(B.TODATE, '%H:%i') TODATE
, DATE_FORMAT(B.FROMDATE, '%H:%i') FROMDATE
FROM PM_CALENDAR A
LEFT OUTER JOIN PM_COMMUTE B
ON A.DATECHAR = B.WORKDAY
WHERE SUBSTRING(A.DATECHAR,1,6) = '202004'
-- AND B.CMPCD = 'P0001'
-- AND B.USERCD = 'admin'
사용자 조건이 없기 때문에 모든 사용자에 대한 근태내역이 나옵니다.
원인은 조건을 잘못된 위치에 준 것에 있었습니다.
쿼리 실행 순서에 대한 이해가 있다면 조금 더 쉽게 접근할 수 있습니다. 쿼리 실행 순서는 아래처럼 ON 절이 우선에 있습니다. 따라서 ON 절이 선순위가 됩니다.
- FROM
- ON
- JOIN
- WHERE
- GROUP BY
- CUBE | ROLLUP
- HAVING
- SELECT
- DISTINCT
- ORDER BY
- TOP
그렇다면 Outer Join으로 연결되는 테이블(PM_COMMUTE, Null로 채워지는 부분)에 대한 조건은 어느 위치에 주는 것이 맞을까요.
SELECT
DISTINCT
B.CMPCD
, A.DATECHAR
, B.WORKDAY
, B.USERCD
, DATE_FORMAT(B.TODATE, '%H:%i') TODATE
, DATE_FORMAT(B.FROMDATE, '%H:%i') FROMDATE
FROM PM_CALENDAR A
LEFT OUTER JOIN PM_COMMUTE B
ON A.DATECHAR = B.WORKDAY
AND B.CMPCD = 'P0001'
AND B.USERCD = 'admin'
WHERE SUBSTRING(A.DATECHAR,1,6) = '202004'
Outer Join으로 연결되는 테이블(Null로 채워지게 될)에 대한 조건은 ON 절에 추가로 작성해주는 것이 맞습니다.
기준이 되는 테이블(PM_CALENDAR)에 대한 조건은 WHERE 절에 작성해주면 됩니다.
+ 피드백은 언제나 환영입니다 :)