오늘은 간단하게 mysql에서 유용하게 쓸 수 있는 함수인 if문을 하나 알아보겠습니다. 다음과 같이 작성합니다.

 

 

if(cond1,eval1,eval2)

 

 

 이것은 cond1이 참일 때, eval1이 평가되고, 아니라면 eval2가 평가됩니다. 이것을 순서도로 나타내면, 아래 그림과 같습니다.

 

 

 엑셀의 그 함수와 매우 유사해 보입니다. 어떻게 쓰는 지 간단하게 예제를 보고, 해커랭크에 나온, 심화 문제를 같이 풀어보도록 하겠습니다.

 

 


 먼저 worker 테이블을 봅시다. 그러면 아래와 같이 되어 있습니다.

 

 

 salary가 NULL 값인 필드가 있는데요. 아차. 제가 신입 사원 분들의 월급을 넣는 것을 깜빡 했지 뭡니까? 'Arie'와 'David'가 신입 사원인데요. 이들은 5000 단위의 월급을 받습니다. 물론 set에 where 조건을 넣어서 업뎃을 할 수도 있겠지만, 귀찮으니, 그냥 조회만 해 봅시다.

 

 일단 salary가 null 값일 때, 5000 단위의 월급을 받아야 합니다. 그러면 condition이 salary is null이 됩니다. 만약에 맞다면 어떻게 해야 하나요? 값 5000이 평가가 되어야 합니다. 아니라면 그냥 salary 필드의 값이 평가가 되어야 될 겁니다.

 

 

 그러면 요렇게 쓰면 되는데요. 이 때 eval1은 5000, eval2는 salary가 되는 셈입니다. 이걸 그대로 쿼리문으로 작성하면 아래와 같습니다.

 

 

 그러면, 그걸 반영하였을 때, 직원들의 월급 총 합은 어떻게 구해야 할까요? 일단 이 테이블의 결과 테이블은 다음과 같이 나올 겁니다. 그러면 이 Table을 가지고 뭔가 요리를 해야 할 거 같은데 말입니다.

 

 

 그럴려면 from절에 해당 결과가 들어가야 겠어요. 그런가요? 따라서, from 절에 위에 작성했던 쿼리를 서브 쿼리로 넣어버린 다음에, select 절에 sum(salary)를 넣으면 됩니다.

 

 

 그러면 이제 응용된 문제를 풀어보도록 합시다.

 


 먼저 테이블은 <node,parent> 쌍으로 주어져 있습니다. 이 데이터는 Tree임이 보장이 되고, parent가 NULL인 경우 부모가 없다는 뜻입니다. 즉 Root라는 소리입니다. 이 때, 해당 노드가 루트인지, 리프인지, 그렇지 않은지를 노드 번호와 함께 출력하라는 쿼리를 작성하라는 것이 문제입니다. 단, 노드 번호는 오름차순으로 정렬하면 좋겠네요.

 

 

 사실, 제가 이 문제를 풀기 위해 작성했던 쿼리는 아래와 같습니다.

 

 아. 뭔가 복잡해 보이는군요. 사실 이렇게 짜도 맞았다고는 할 건데 뭔가 비효율적인 거 같습니다. 이걸 제가 어떻게 작성했는지 신기할 정도네요. 일단, 문제를 단순화 시켜 봅시다. 우리는 루트냐 아니냐를 판단하기가 더 쉽습니다.

 

 

 그러면 p가 null이냐를 판단해서 null이면 'root'라는 값을 반환하면 될 거에요.

 

 

 실행 결과는 다음과 같이 나옵니다. 

 

 

 제 의도대로 나왔으니 성공적입니다. 그 다음에 무엇이 문제인가요? p가 null 값을 가지지 않는 경우가 문제가 될 수 있는데요. 이 때에는 어떻게 해야 할까요? eval2에 뭔가를 넣어야 할 거 같은데요. 또 다시 조건을 판단해야 합니다. 그런데 어떤 걸 판단해야 하죠? 보면, <N,P> 쌍이 있을 때, <3,2>라는 쌍이 있다면, 2는 3의 부모입니다. 즉, 2는 3을 자식으로 가지고 있기 때문에, 리프가 아닙니다. 그러면 이걸 어떻게 판단하면 좋을까요?

 

 일단, BST 테이블에서 P = 해당 노드 번호인 레코드만 뽑았을 때, 레코드의 갯수가 0이 아니라면, 리프가 아닙니다.

 

 그러면 대충 이런 식으로 쿼리를 작성하였을 때, cond이면 'Inner'이고 그렇지 않으면 'leaf'가 나와야 한다는 소리가 됩니다. 그러면 cond는 어떻게 평가하면 좋을까요?

 

 

 간단합니다. 일단 P값이 node인 것의 갯수는 아래와 같이 작성할 수 있습니다.

 

 그러면 cond에, 이 쿼리를 넣으면 될 거에요.

 

 

 저는 바깥 쿼리에서 N을 node로 바꾸었어요. 3번째 ~ 7번째 쿼리에서의 BST 테이블에서 뽑아오는 N과 혼동이 될 여지가 있기 때문입니다. 1번째 줄에 N as node라고 했는데요. 이 node 값을 if 함수의 평가식에 넣습니다. 그러면, 바깥쪽에서의 node와, 안쪽에서의 P와 헷갈릴 여지가 없어요.

 

 안쪽에서 무엇을 하고 있나요? 예를 들어 바깥쪽에서 5번 노드를 node 필드에 가져 왔다고 해 봅시다. 그것의 부모가 7이라면, 2번째 줄이 평가가 됩니다. 그리고, 3번째 줄에 있는, 서브 쿼리로 들어가게 되는데요. 이 때, node는 5입니다. P의 값이 5인 결과값의 갯수를 BST에서 찾고 있나요? 그것의 갯수가 0보다 크다면 'Inner'를, 그렇지 않다면 'Leaf'를 출력하게 됩니다.