如何根据PostgreSQL第2部分中的枚举列总结所有行?

时间:2015-06-30 18:19:39

标签: postgresql function triggers sum

))大家好,这是我的桌子......

enter image description here

目前我正在使用此功能触发...

IF NEW.timetype = 'Total' THEN
  SELECT SUM(timeelapse) FROM (SELECT DISTINCT ON (floor(timeindex)::int) floor(timeindex)::int timeindex, timeelapse FROM mytable WHERE pcnum = NEW.pcnum AND fnname = NEW.fnname AND timetype = 'Lap' ORDER BY 1, 2 DESC) alias INTO v_sumtimeelapse_fn;
    IF FOUND THEN
      NEW.timeelapse := v_sumtimeelapse_fn;
    ELSE
      RAISE EXCEPTION USING MESSAGE = 'There is not any previous row...';
    END IF;
END IF;

所以无论什么时候总计'在时间类型列上插入它,它会使所有时间从表格中删除WHERE pcnum = NEW.pcnum和fnname = NEW.fname AND timetype =' Lap'但只有在timeindex具有最高百分位值的情况下(在mytable中它们将是前三个天蓝色高亮方格= 00:01:00,00:03:00,00:04:00(1.001,2.003,3.003))并放置导致NEW.timeelapse(在mytable中它将是第一个蓝色突出显示的方块= 00:08:00)

该函数正确地生成了SUM,但我想再添加两个规则......

  1. 当' Total'如果函数没有找到任何' Lap'是按时间类型插入的。在一个'开始' (两者都有相同的pcnum和fnname)然后它应该显示错误消息"'没有任何Lap ..." (在mytable中,它将是红色突出显示的方块)。请注意,没有任何' Lap' of fnname =' bbbb'在'开始' fnname =' bbbb'。我尝试设置我的功能,使用...

    RAISE EXCEPTION USING MESSAGE = 'There is not any previous row...'
    
  2. 但如果我插入总计'它就行不通。在那种情况下,简单地将NEW.timeelapse留空。

    1. 该函数应该使用所有已设置的规则来计算时间偏移,但仅限于那些低于最后一个(后代)' Total'相同的pcnum和fnname(在mytable中它将是第二个蓝色突出显示的方块)请注意,它仅仅是在最后一个(descendet)' Total'之后的timeelapses。 (在mytable中它将是第四个突出显示方块的天蓝色)。
    2. 谢谢高级。

1 个答案:

答案 0 :(得分:0)

要从早于最后Total的计算行中排除,您可以在附件查询中使用主键。 声明新变量v_fnserial。 查找给定fnserialpcnum的最后一次出现“总计”的行的fnname,并将值指定给v_fnserial。 在主查询中添加条件fnserial > v_fnserial

当主查询返回null时,您应该引发异常。

IF NEW.timetype = 'Total' THEN
    SELECT fnserial INTO v_fnserial
    FROM mytable 
    WHERE timetype = 'Total' AND pcnum = NEW.pcnum AND fnname = NEW.fnname
    ORDER BY fnserial DESC LIMIT 1;

    SELECT SUM(timeelapse) FROM (
        SELECT DISTINCT ON (floor(timeindex)::int) floor(timeindex)::int timeindex, timeelapse 
        FROM mytable 
        WHERE fnserial > coalesce(v_fnserial, 0) AND pcnum = NEW.pcnum AND fnname = NEW.fnname AND timetype = 'Lap' 
        ORDER BY 1, 2 DESC) alias 
    INTO v_sumtimeelapse_fn;
    IF v_sumtimeelapse_fn NOTNULL THEN
        NEW.timeelapse := v_sumtimeelapse_fn;
    ELSE
        RAISE EXCEPTION USING MESSAGE = 'There is not any previous row...';
    END IF;
END IF;