2014-11-11 5 views
2

합니다다른 테이블에서 두 개의 열을 비교하고 내가 두 테이블이 삽입

내가 열 fld_allocated_days을 비교하는 함수를 만들고 싶어 tbl_project에서 (fld_id)에

1.Tbl_project 

fld_id fld_allocated_days 
1  10 
2  3 
3  1 
4  99 

2.Tbl_project_timesheet 

fld_id fld_allocated_time fld_project_id 
1  8.00    1 
2  8.00    1 
3  8.00    2 
4  8.00    3 
5  8.00    2 
6  8.00    2 
7  8.00    1 
8  8.00    4 
9  8.00    1 

--fld_project_id 참조 tbl_project_timesheet의 열 SUM (fld_allocated_time)이있는 테이블 tbl_project에서.

첫 번째 열 (fld_allocated_time)이 두 번째 (fld_allocated_days)보다 낮 으면 테이블 tbl_project_timesheet에 삽입하십시오.

함수 매개 변수 중 하나는 할당 된 시간을 삽입 할 프로젝트를 선택하는 p_project_id입니다.

할당 된 시간을 삽입하지만 할당 된 시간을 초과하는지 확인하지 않는 기능이 있습니다.

CREATE OR REPLACE FUNCTION function_add_timesheet_record(p_project_id integer, p_allocated_time numeric) 
    RETURNS void AS 

BEGIN 

INSERT INTO tbl_project_timesheet(fld_project_id,fld_allocated_time) 
    VALUES (p_project_id, p_allocated_time); 
END 
+1

8 행당 최대 시간은 얼마입니까? 나는. 차이가 15 시간이라면 무엇이 필요합니까? 15 시간의 인서트 또는 2 개의 인서트 - 8 개 중 하나는 7 시간? –

+1

실제로'8.00' 값은 무엇을 의미합니까? 8 분, 8 시간, 8 일? ... –

+0

아, 좋은 질문, 내 실수로 죄송합니다. 8.00 시간입니다. 프로젝트 ID로 모든 행을 합산하여 3이라고 말한 다음 fld_allocated_days와 비교해보십시오. 그리고 예 8은 프로젝트에서 행당 하루당 최대 시간입니다. – Alienware

답변

1

위의 의견을 바탕으로, 우리는 tbl_project에서 1 day 테이블 tbl_project_timesheet에서 8 hours 동일하다는 가정을합니다. 이렇게하면 제공된 데이터를 프로젝트 1에 대해 6 일 누락하고 프로젝트 4에 대해 98 일을 누락하게됩니다. 이러한 데이터를 초 단위로 변환하고 두 테이블의 값을 비교합니다.

그런 다음 전체 일수에 대해 8th로 배열을 채우고 나머지 부분으로 배열을 추가합니다 (불완전한 날짜가있는 경우).

그런 다음 배열을 중첩 해제하여 각 행 (하루) 당 8 시간을 갖습니다. 마지막으로 데이터를 삽입합니다.

WITH 
    d AS (
    SELECT 
     p.fld_id, 
     p.fld_allocated_days * 8 * 3600 - COALESCE(
     SUM(
      EXTRACT(epoch FROM t.fld_allocated_time)::int 
     ), 
     0) AS diff 
    FROM 
     tbl_project p LEFT JOIN tbl_project_timesheet t 
    ON 
     p.fld_id=t.fld_project_id 
    GROUP BY 
     p.fld_id 
), 
    agg_d AS (
    SELECT 
     fld_id, 
     UNNEST(
     ARRAY_APPEND(
      ARRAY_FILL(
      '8:00'::time, 
      ARRAY[(diff/(3600 * 8))::int] 
     ), 
      ((diff % (3600 * 8)) * interval '1 second')::time 
     ) 
    ) AS hours FROM d 
    WHERE 
     diff > 0 
) 
INSERT INTO tbl_project_timesheet 
    (fld_project_id, fld_allocated_time) 
SELECT 
    fld_id, hours 
FROM 
    agg_d 
WHERE 
    hours > '0:0'::time; 
+0

고마워, 고마워. – Alienware