2015-06-30 41 views
0

))大家好,这是我的表...如何基于PostgreSQL part2中的枚举列总结所有行?

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; 

所以每当 '总' 插在timetype列它总结了所有的timeelapse FROM mytable WHERE pcnum = NEW.pcnum AND fnname = NEW.fname AND timetype ='Lap',但只有timeindex具有最高的百分数值(在mytable中,它们将是前三个skyblue高亮度平方= 00:01 :00,00:03:00,00:04:00(1.001,2.003,3.003))并将结果放入NEW.tim eelapse(在MYTABLE这将是第一个蓝色突出平方= 00:08:00)

功能正常,使之和,但我想两个规则添加到它...

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

    RAISE EXCEPTION USING MESSAGE = 'There is not any previous row...' 
    

,但它只是不工作,如果我在那种情况下插入一个“总”,它简单的离开NEW.timeelapse空值。

  1. 该函数应该将timeelapse与其所有已设置的规则进行SUM,但仅限于那些位于同一pcnum和fnname的最后(后代)'Total'它将成为第二个蓝色突出显示的正方形)请注意,它仅累计在最后(下划线)'Total'之后的timeelapses(在mytable中,它将成为第四个用skyblue突出显示的正方形)。

Thanks Advanced。

回答

0

要从计算行中排除早于Total的计算行,可以在附件查询中使用主键。 声明新变量v_fnserial。 找到和fnname的最后一次出现'Total'的fnserial,并将值赋给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; 
+0

我这样做(与fnserial的东西),但包括在主'选择SUM'一个括号里面,像这样...'选择SUM(timeelapse) FROM(SELECT DISTINCT ON(地板( timeindex):: int)floor(timeindex):: int timeindex,timeelapse FROM mytable WHERE pcnum = NEW.pcnum AND fnname = NEW.fnname AND timetype ='Lap'AND fnserial>(SELECT fnserial FROM mytable WHERE pcnum = NEW。 pcnum AND fnname = NEW.fnname AND timetype ='Total'ORDER BY fnserial DESC LIMIT 1)ORDER BY 1,2 DESC)别名INTO v_sumtimeelapse_perfn; 如果FOUND THEN',但它不是SUM最后的'总是的,可以吗?谢谢 – litu16

+0

也在函数的结尾,我使用了'IF FOUND THEN'而不是'IF v_sumtimeelapse_fn NOTNULL THEN'它可以吗? THanks – litu16

+0

我一直在尝试使用'IF v_sumtimeelapse_fn NOTNULL THEN'来代替'IF FOUND THEN'。但是这个函数有一个bug,它只有在表中有相同的fnname和timetype的前一个'Total'时才起作用,如果没有任何前一个,它会发送'RAISE EXCEPTION USING MESSAGE'我们能做什么??? THanks – litu16