MariaDB에서 WITH 구문을 통해 CTE를 사용 시 주의할 점이 있어서 기록을 남깁니다.
- CASE 1) MariaDB 접속 시 스키마 명을 명시 할 경우. jdbc:mariadb://localhost:3306/schema_name
- CASE 2) MariaDB 접속 시 스키마 명을 지정하지 않을 경우. jdbc:mariadb://localhost:3306/
위의 같이 MariaDB 접속 시 스키마명을 지정할 때와 하지 않을 경우 차이가 발생합니다.
우선 스키마명을 지정하여 접속할 경우 입니다.
WITH CTE_NAME AS (
SELECT *
FROM TABLE_NAME
), CTE_NAME2 AS (
SELECT *
FROM CTE_NAME
), CTE_NAME3 AS (
SELECT *
FROM TABLE_NAME2
), CTE_NAME4 AS (
SELECT *
FROM CT_NAME2
)
SELECT *
FROM CTE_NAME4
위의 예시와 같이 이전에 선언된 CTE의 임시 결과물을 다른 CTE 내에서 사용하거나 최종 쿼리에서 사용할 수 있습니다.
다음은 스키마명 없이 접속을 할 경우 입니다.
WITH CTE_NAME AS (
SELECT *
FROM TABLE_NAME
), CTE_NAME2 AS (
SELECT *
FROM CTE_NAME
), CTE_NAME3 AS (
SELECT *
FROM TABLE_NAME2 TN2
INNER JOIN CTE_NAME2 CN2 ON TN2.ID = CN2.ID
), CTE_NAME4 AS (
SELECT *
FROM CTE_NAME3
)
SELECT *
FROM CTE_NAME4
위의 사용된 쿼리는 차이점을 보여 드리기 위한 예시 이므로 감안하고 봐주시기 바랍니다.
첫번째 예시와의 차이점은 CTE의 임시 결과물을 바로 아래 CTE에서만 사용하고 있다는 점입니다.
두번째 예시에서 아래와 같이 사용하게 되면 에러가 발생합니다.
... 중략
), CTE_NAME4 AS (
SELECT *
FROM CTE_NAME2
)
... 중략
위와 같이 CTE_NAME4에서 CTE_NAME2의 임시 결과물을 참조할 경우 No database 라는 에러가 발생합니다.
이는 스키마를 지정하지 않을 경우 발생하는 에러입니다.
여기서 특이한 점은 첫번째 CTE_NAME의 임시 결과물은 CTE_NAME2, CTE_NAME3, CTE_NAME4, 최종 쿼리 어디든 사용해도 된다는 점입니다.
위와 같은 에러를 피하기 위해서는 CTE_NAME4에서 CTE_NAME2의 쿼리문을 직접 사용하시거나 CTE_NAME4에서 중첩 WITH 구문을 활용하여 임시 결과물을 사용하는 방법입니다.
WITH CTE_NAME AS (
SELECT *
FROM TABLE_NAME
), CTE_NAME2 AS (
SELECT *
FROM CTE_NAME
), CTE_NAME3 AS (
SELECT *
FROM TABLE_NAME2 TN2
INNER JOIN CTE_NAME2 CN2 ON TN2.ID = CN2.ID
), CTE_NAME4 AS (
WITH CTE_NAME2_1 AS (
SELECT *
FROM CTE_NAME
)
SELECT *
FROM CTE_NAME2_1
)
SELECT *
FROM CTE_NAME4
위의 예시처럼 CTE_NAME4 안에서 WITH CTE_NAME2_1과 같이 또 다른 CTE 임시 결과물을 만들어 사용하는 방법입니다.
지금까지 MariaDB에서 CTE 사용 시 주의점에 대해 적어보았습니다. 저의 경우 부득이하게 CTE를 사용할 일이 많아서 사용하였지만 해당 기능을 많이 사용할 경우 성능상 이슈가 발생할 수 있으므로 주의하시기 바랍니다.