【问题标题】:Compare two columns from different table and make the insertion比较来自不同表的两列并进行插入
【发布时间】:2015-01-08 03:16:56
【问题描述】:

我有两张桌子:

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 的 (fld_id)

我想创建一个函数,将表 tbl_project 中的 fld_allocated_days 列与 tbl_project_timesheet 中的列 SUM(fld_allocated_time) 进行比较。

如果第一列(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

【问题讨论】:

  • 每行的最大小时数是 8 小时吗? IE。如果差值为 15 小时,您需要什么 - 一个插入 15 小时,或两个插入 - 一个插入 8 小时,另一个插入 7 小时?
  • 其实8.00代表的值是什么? 8 分钟、8 小时、8 天?...
  • 啊,好问题,对不起我的错误,8.00 是小时,我需要将所有具有项目标识的行相加,比如说 3 并与列 fld_allocated_days 进行比较,它以小时而不是天为单位。是的 8 是项目中每行和每天的最大小时数。
  • 插入并不重要,因为如果比较没问题,我像其他数字一样插入。

标签: sql postgresql stored-procedures postgresql-9.1


【解决方案1】:

基于上面的 cmets,我们假设来自tbl_project1 day 等于来自表tbl_project_timesheet8 hours。这样,根据您提供的数据,项目 1 缺少 6 天,项目 4 缺少 98 天。我们将它们转换为秒并比较两个表中的值。

然后我们用 8ths 填充一个数组作为整天的数量,并将除法的其余部分附加到数组中(以防天数不完整)。

然后我们取消嵌套数组,这样我们每行(每天)有 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;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-09-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-02
    相关资源
    最近更新 更多