SQL 코드카타 181번
181번~183번까지는 모두 Alternative Query에 관련된 문제다.
문제에서 따로 테이블을 정해주거나 뭘 쓰면 된다고 힌트를 준 것도 없어서, 임시로 CTE를 만들어서 푸는 방법밖에 없을 것 같다.
희한하게 여태까지는 CTE를 쓰면 오류가 났는데 이 문제에서는 CTE를 써도 정답으로 처리되었다_-
WITH RECURSIVE numbers AS (
SELECT 20 AS n
UNION ALL
SELECT n - 1
FROM numbers
WHERE n > 1
)
SELECT REPEAT('* ', n)
FROM numbers;
위의 문제에서 CTE의 로직만 바꿔주면 된다.
WITH RECURSIVE numbers AS (
SELECT 1 AS n
UNION ALL
SELECT n + 1
FROM numbers
WHERE n < 20
)
SELECT REPEAT('* ', n)
FROM numbers;
CTE에 의해 n이 1부터 20까지 증가할 것이고,
본 쿼리에서 별(*)이 n만큼 반복(REPEAT)되면서 출력된다.
SQL 코드카타 183번
마지막은 1부터 1,000까지의 소수(prime number)를 &로 연결하면서 출력하는 쿼리를 짜는 문제. 예컨대 10까지의 소수 조합은
2&3&5&7
이런 형태로 출력되면 된다. 여기서도 CTE부터 정의한 후에 본 쿼리를 짜는 방식으로 접근해 보면,
WITH RECURSIVE numbers AS (
SELECT 2 AS n
UNION ALL
SELECT n + 1
FROM numbers
WHERE n < 1000),
먼저 위 문제들과 똑같이 재귀적인 성질을 가진 CTE를 먼저 만들어 준다.
n은 가장 작은 소수인 2부터 시작해서 1,000에 도달할 때까지 1씩 증가하면서 합쳐지게 된다.
WITH RECURSIVE numbers AS (
SELECT 2 AS n
UNION ALL
SELECT n + 1
FROM numbers
WHERE n < 1000
),
primes AS (
SELECT n
FROM numbers num
WHERE NOT EXISTS (
SELECT 1
FROM numbers divisor
WHERE divisor.n < num.n AND divisor.n > 1 AND num.n % divisor.n = 0
)
이제 위에서 만든 number CTE를 참조해서 소수(prime) CTE를 만든다.
MySQL에서 소수는 1보다는 크고 n보다는 작은 어떤 수들(divisor.n)에 대하여, n이 그 수들로 나누어 떨어지는(num.n % divisor.n = 0) 경우가 없는(NOT EXIST조건) 조건을 만족하면 된다. 예를 들어 n이 5일 때는 1보다 크고 5보다는 작은 수 2,3,4에 대하여 5가 2,3,4로 나누었을 때 0이 되는 경우가 없으므로 5는 prime에 해당하는 식이다. 오히려 소수를 구현하는 조건은 파이썬보다 SQL이 더 간단한 것 같다.
마지막으로, prime CTE에 들어가 있는 소수들을 &로 연결하면서 불러오는 본 쿼리를 작성해 주면 정답이다.
WITH RECURSIVE numbers AS (
SELECT 2 AS n
UNION ALL
SELECT n + 1
FROM numbers
WHERE n < 1000
),
primes AS (
SELECT n
FROM numbers num
WHERE NOT EXISTS (
SELECT 1
FROM numbers divisor
WHERE divisor.n < num.n AND divisor.n > 1 AND num.n % divisor.n = 0
)
)
SELECT GROUP_CONCAT(n ORDER BY n SEPARATOR '&')
FROM primes;
GROUP_CONCAT은 예전 코드카타에서 한 번 썼던 적이 있는 함수인데 정말 오랜만에 다시 써 보게 됐다. n을 SEPARATOR '&'로 합쳐가면서 출력하고, 이 때 n의 순서는 오름차순에 의한다. (ORDER BY n) 만약 내림차순으로 출력하고 싶으면 ORDER BY n DESC로 적어주면 된다.
드디어 183번까지 모든 코드카타를 다 풀었다🥳
내일부터 아침 코드카타 시간은 리트코드나 다른 소스에서 문제를 더 구해서 풀거나, 이제까지 풀었던 코드카타에서 어려웠던 문제들만 다시 해결하면서 정리해 보는 시간으로 써야겠다.