database.sarang.net
UserID
Passwd
Database
DBMS
MySQL
ㆍPostgreSQL
Firebird
Oracle
Informix
Sybase
MS-SQL
DB2
Cache
CUBRID
LDAP
ALTIBASE
Tibero
DB 문서들
스터디
Community
공지사항
자유게시판
구인|구직
DSN 갤러리
도움주신분들
Admin
운영게시판
최근게시물
PostgreSQL Q&A 7521 게시물 읽기
No. 7521
일별자료의 주별자료 변환 함수
작성자
chunrima
작성일
2008-09-15 08:40
조회수
7,004

안녕하세요.

일별자료(Daily)를 7일간 합산하여 주별자료 (Weekly)료 변환하려 하는데 도움부탁 드립니다.


과정 1. (함수설정)

강성일님의 함수이용 (http://database.sarang.net/?inc=read&aid=6619&criteria=pgsql&subcrit=&id=&limit=20&keyword=for+loop&page=1)

 

-- source:http://database.sarang.net/?inc=read&aid=6619&criteria=pgsql&subcrit=&id=&limit=20&keyword=for+loop&page=1


CREATE OR REPLACE FUNCTION "public"."cdate" (date, date,interval) RETURNS SETOF "pg_catalog"."record" AS

$body$

DECLARE

node1 record;

subnode record;

BEGIN


FOR node1 IN SELECT to_date($1 + $3,'YYYY-MM-DD') as cdate where to_date($1 + $3,'YYYY-MM-DD')<= $2 LOOP

RETURN NEXT node1;

FOR subnode IN SELECT * FROM cdate(node1.cdate, $2,$3) as t(cdate date) LOOP

RETURN NEXT subnode;

END LOOP;

END LOOP;


RETURN;

end;

$body$

LANGUAGE 'plpgsql' VOLATILE CALLED ON NULL INPUT SECURITY INVOKER;

-- end of function --


과정 2: (날짜 테이블 생성)


DROP TABLE mydate;

CREATE TABLE mydate AS SELECT * FROM cdate('1982-12-31'::date,'1984-12-31',interval'1 day') as t(cdate date);

SELECT * FROM mydate;


+++++++++++++++++++

cdate

+++++++++++++++++++

1983-01-01

1983-01-02

1983-01-03

....

...

1984-12-31


과정3: (테스트 테이블 생성)

-- create test table --

DROP TABLE test;


CREATE TABLE test

(

  staid character varying(12),

  date date,

  stidx character varying(7),

  val double precision

)

WITHOUT OIDS;


SELECT * FROM test;

++++++++++++++++++++++

staid  date  val

++++++++++++++++++++++


과정 4: (테스트 테이블 자료입력)

DROP FUNCTION create_test_table();


CREATE FUNCTION "create_test_table" () RETURNS text AS '

  DECLARE

    cdate_this date;

    text_out date;

    row_data mydate%ROWTYPE;

  BEGIN

        -- FOR i IN 1..(SELECT count(*) FROM mydate) LOOP

          FOR row_data IN SELECT * FROM mydate LOOP

             SELECT INTO cdate_this cdate FROM mydate;

             text_out := row_data.cdate;

                 INSERT INTO test(staid,date,val) VALUES (0100105,text_out, trunc(1000*random()));

               -- IF i < (select count(*)/2 from mydate) THEN

               --   INSERT INTO test(staid,date,val) VALUES (0100105,text_out, trunc(1000*random()));

               -- ELSE

               --   INSERT INTO test(staid,date,val) VALUES (0100777,text_out, trunc(1000*random()));

               -- END IF;

           --END LOOP;

        END LOOP;

    RETURN text_out;

  END;

' LANGUAGE 'plpgsql';


select create_test_table();

select * from test;


++++++++++++++++++++

staid     date          val

100105  1983-01-01  251

100105  1983-01-02  664

100105  1983-01-03  762

.....

.....

100105  1984-12-31  603


과정 5: (주별자료로 전환)

SELECT staid, date_trunc('week', date) as weekly, sum(val) as weeklyflow FROM test group by staid, date_trunc('week',date) order by weekly;


+++++++++++++++++++++

staid     weekly                       weeklyflow

100105  1982-12-27 00:00:00-06  915

100105  1983-01-03 00:00:00-06  4153

100105  1983-01-10 00:00:00-06  3116

.....

.....

100105  1984-12-24 00:00:00-06  1606

100105  1984-12-31 00:00:00-06  603


질문:


1. 왜, 날짜를 1983-01-01 에서 1984-12-31 일간 주별 (7일 합산)을 요청했는데, 왜 결과가 1982-12-27 (과정 5) 부터 출력이 되는지요?

2. 보통 평년이 365일이라 1년을 정확하게 52주로 계산하고 싶은데 1월1일부터 시작을 하면 7일을 합산하여 1 주로 계산하여 매해 마지막일인 12월 31일을 제거하여 총 52주 (364/7 = 52주)로 만들고 싶습니다.

즉, 결과값이

++++++++++++++++++++++++++++++

staid     weekly                       weeklyflow

100105  1983-01-07 00:00:00-06  915

100105  1983-01-14 00:00:00-06  4153

....

....

100105  1984-12-30 00:00:00-06  586


3. 그런데, 1984년 같은 경우는 윤달이 (2월달이 29일까지 있음)있어, 총일수가 366일이 되어, 이 같은 경우는 마지막 12월 30일과 31일을 제거하여 총 52주로 만들고 싶습니다.

도움부탁드립니다.








이 글에 대한 댓글이 총 1건 있습니다.

date_trunc 에서의 week 는 입력받은 날짜가 주간 처음 날을 구할 때 쓰네요.

주간의 처음은 월요일로 한다네요.

     12월 2007
일 월 화 수 목 금 토
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31
1월 2008
일 월 화 수 목 금 토
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31

이런 달력에서 2008-01-05의 date_trunc week 값은 당연히 2007-12-31 이 나올 것 같습니다. 

-------------

week 라는 개념을 단지 7일이라는 것만 고려한다면,

그냥 extract() 함수의 doy 값을 사용하는게 더 낫지 않을까싶습니다.

덕분에 요일 관련을 조금 살펴봤는데,

제일 재미난 것이 extract() 함수의 week 처리 방법이네요.



김상기(ioseph)님이 2008-09-18 12:28에 작성한 댓글입니다.
[Top]
No.
제목
작성자
작성일
조회
7526mssql의 링크드서버와 같은 기능을 하는게 있는지 궁금합니다. [1]
링크드서버
2008-09-29
6142
7525같은 데이트 베이스를 pg_restore 한 후의 용량차이? [2]
초보
2008-09-29
6041
7523Restore 중 에러문제 [1]
초보
2008-09-19
5940
7521일별자료의 주별자료 변환 함수 [1]
chunrima
2008-09-15
7004
7520libpq에서 쿼리 날리듯 function이나 pl/pgsql날리는 방법? [1]
ㅎㅎ
2008-09-13
6030
7518프로시저 검색 [1]
유닉스
2008-09-11
6203
7517parallel 하게 DB update시 문제점 [1]
디비
2008-09-10
6089
Valid XHTML 1.0!
All about the DATABASE... Copyleft 1999-2024 DSN, All rights reserved.
작업시간: 0.021초, 이곳 서비스는
	PostgreSQL v16.2로 자료를 관리합니다