PostgreSQL 숫자/날짜 레코드 데이터 만들기 - generate_series

PostgreSQL DB 를 사용하면서 날짜 혹은 숫자를 여러행으로 리턴하는 함수가 필요해서 찾아보았다. generate_series 함수를 이용하면 별도 테이블을 create 하지 않아도, 손쉽게 연속하는 숫자 또는 날짜 리스트를 만들 수 있다.

Set Returning Functions

PostgreSQL 문서를 보면, Set Returning Functions 라는 용어로 정의되어 있다. 아래 예제들을 보면 이용방법을 굳이 설명하지 않아도 이해할 수 있을 것이다.

select generate_series(1, 5) col_name;

col_name
--------
       1
       2
       3
       4
       5
select generate_series(2, 10, 2) col_name;

col_name
--------
       2
       4
       6
       8
      10
select generate_series('2022-03-31'::date, 
	'2022-04-05'::date, '1 day'::interval)::date col_date;

col_date  
----------
2022-03-31
2022-04-01
2022-04-02
2022-04-03
2022-04-04
2022-04-05    
SELECT * FROM generate_series('2023-01-01 00:00'::timestamp,
	'2023-01-03 12:00', '8 hours');

generate_series        
-----------------------
2023-01-01 00:00:00.000
2023-01-01 08:00:00.000
2023-01-01 16:00:00.000
2023-01-02 00:00:00.000
2023-01-02 08:00:00.000
2023-01-02 16:00:00.000
2023-01-03 00:00:00.000
2023-01-03 08:00:00.000

JOIN 할때 Alias 설정방법

다른 테이블과 join 시에 select 문을 만들어서 한번 감싸는 방법이 하나 있고, ()로 감싸지 않고, 바로 from 절에서 선언해서 사용할 수도 있다. 그 2번째 방법보면 A(aa)와 같이 뒤에 붙였는데, 다른 테이블과 join 하기 위해서는 명칭이 있어야 하기 때문이다. 테이블명으로는 A으로 별칭을 주고, 컬럼명에는 aa 로 별칭을 붙여서 join 할때 사용했다.

-- case1
select *
  from (select generate_series(1, 10) aa) A
  left outer join 
       (select generate_series(1, 10, 3) bb) B
  on A.aa = B.bb

-- case2
select * 
  from generate_series(1, 10) A(aa)
  left outer join 
       generate_series(1, 10, 3) B(bb)
  on A.aa = B.bb
  ;

-- 조회결과
aa|bb
--+--
 1| 1
 2|  
 3|  
 4| 4
 5|  
 6|  
 7| 7
 8|  
 9|  
10|10

더 보면 좋을 글들