2018년 5월 7일 월요일

[Postgresql] arrag_agg와 if문을 사용한 문제.

노드공부방에서 표류중에 db질문이 올라왔는데, 재미있을거 같기도 하고 어려워보이기도 해서 한번 풀어 보기로 했습니다.




주어진 테이블은 위와 같으며,


질문자는 위와 같은 방식의 출력을 원했습니다.

a 와 b 칼럼을 출력하는데, b가 null일때는 아무런 출력물이 없으나, b에 값이 있는경우,
b의 값과 동일한 모든 컬럼들을 하나로 묶어 출력하는것 입니다.

목적은 긴 줄의 질의를 하나의 질의로 압축시키는것 이었습니다.


간단할 줄 알고 무작정 덤볐는데, select문을 몇번 날리다가 당연한 문제에 도달했습니다.

select a,(select * from test) from test; 와 비슷한 방식의 쿼리를 먼저 날렸었는데요,

ERROR: subquery must return only one column
서브 쿼리는 하나의 컬럼만을 리턴해야합니다.

라는 출력문을 날리기만 할 뿐입니다.
그도 그럴것이,


요놈을 어떻게 1차원으로 출력하겠느냐는 생각까지만 하면 당연한 결과인데 말이죠.

우선 위의 결과물을 1차원 배열로 묶는 방법을 검색했고,
array_agg()함수가 제가 찾는 놈이었습니다.




짠! 1차원배열로 결과물들이 나왔습니다.

이제 남은 작업들은,a 와 b 컬럼을 출력하되, b가 null 이 아닌 컬럼에다가 위의 결과를 띄우는것 입니다.


 이제 슬슬 결과물에 근접하고 있습니다.
하지만, b컬럼이 null인가 아닌가를 따지려면 추가적으로 함수가 필요해 보였습니다.

if문을 생각했지만, postgresql에는 if문이 없는 대신
case 문이 존재했습니다.

case when <조건문> then <true일때> else <false일때> end
다행히도 구조는 똑같네요.

이제 b가 널인가 아닌가에 따라 다르게 출력을 해 봅니다.


좀 더 답에 근접했습니다!

마지막으로 다시 질문자가 원한게 뭔지.Araboza


b의 값에 해당하는 컬럼들만 모아서 배열타입으로 출력하는군요!

그럼 array_agg를 출력할때 b가 원하는 값들만 출력되게 바꾸면 되네요!.


제일 부모쿼리의 test 를 testM으로 별명을 지어주어, 부모쿼러의 b값을
서브 쿼리에서 접근이 가등하게 되었으며,
35번 라인에서, 서브쿼리의b 가 보무쿼리b의 값과 동일한것 으로 조건문을 달았습니다.
이로써 array_agg()로 나오는 결과는, 부모 컬럼의 b 값과 동일한 결과만을 가져오게 되죠.


하다보니 오기가 생겨서 붙잡았는데, 의외로 상당한 공부가 되었습니다. 다음 db서버 개발에는 써봐야겠어요.

댓글 없음:

댓글 쓰기