ANSI SQL

NAVIGATION
CATEGORIES
REFERRENCE
LINKS
  • Cumulative Field

    11 answers - 422 bytes - related search similar search Add To My Delicious Add To My Stumble Upon Add To My Google Mark Add To My Facebook Add To My Digg Add To My Reddit

    I have four columns in a table. One called person, days, hours and cumulative. Every day the person works and as a result creates a new entry and thus an entire new row. From this, the day increases e.g. 1 - 2 - 3 etc in each row. The hours that they work is different each day. What i am hoping to achieve is have the forth column showing the total hours that person has work this the first day they started. Any ideas...
  • No.1 | | 687 bytes | |

    Hi,

    Since you posted your question in the SQL forum I presume that you're looking for a query. Her I've got one:

    SELECT person, days, hours,
    (SELECT sum(hours)
    FROM table b
    WHERE b.person = a.person
    AND b.days <= a.days) AS cumulative
    FROM table a

    This should work, at least it does on an Informix database. I'm not shure whether this is standard SQL or not...

    If it's not a query you want but a way of dynamicly filling the fourth column at every insert you could use the subquery inside a trigger to calculate the value to be inserted in the last column.

    Regards
  • No.2 | | 1013 bytes | |

    Which database do you use? On Oracle, you could create a database trigger which would populate the required columns; this would be a nice and clean; for example:CREATE OR REPLACE TRIGGER trg_hours
    BEFORE INSERT ON HOURS_CUM
    FOR EACH ROW
    BEGIN
    SELECT
    NVL(MAX(t.days) + 1, 1),
    NVL(SUM(t.HOURS_worked), 0) + :NEW.HOURS_worked
    INTO :NEW.days, :NEW.cumulative
    FROM HOURS_CUM t
    WHERE person = :NEW.person;
    END;Direct table insert won't be possible (in Oracle) because table is mutating and records can't be accessed (for example, entering 2 hours for person number 1)INSERT INTO HOURS_CUM
    (person, days, HOURS_worked, cumulative)
    (SELECT
    1,
    NVL(MAX(t.days) + 1, 1),
    2,
    NVL(SUM(t.HOURS_worked), 0) + 2
    FROM HOURS_CUM t
    WHERE t.person = 1
    );I guess the same goes for another databases; if you can't use triggers, you'll need to figure out how to bypass such a limitation (if it exists).
  • No.3 | | 136 bytes | |

    On Oracle, you could create a database trigger
    The same holds for DB2.
    But replace NVL by COALESCE then. (Also works on Oracle.)
  • No.4 | | 557 bytes | |

    ... have the forth column showing the total hours ...
    An other solution consists of redefining your table:
    - Have a differently named table with just the first three columns.
    - Create a VIEW (with the name of the old table): CREATE VIEW mytable AS
    SELECT person, days, hours,
    (SELECT SUM(hours)
    FROM oldtable
    WHERE person = t.person AND days <= t.days) AS cumulative
    FROM oldtable AS aThis way, you may insert into "oldtable", and read from "mytable".
  • No.5 | | 443 bytes | |

    Can anyone tell me how to size the "Code" section so it won't appear with a fixed size and a scrollbar? I've been trying some things now, without the wanted result...

    Thanks,
    Hans

    BTW: With Informix it's possible to dynamically store a value in a column of an inserting row. It has to be done with an insert trigger that a invokes a stored function which returns it's value INTO the specified column.
  • No.6 | | 102 bytes | |

    Don't think this is possible...
    It's a feature of the dBforums lay-out, I'm afraid.
  • No.7 | | 251 bytes | |

    Which database do you use? On Oracle, you could create a database trigger which would populate the required columns; this would be a nice and clean;

    Unfortunatrely this trigger solution posted may produce a "mutating table" error. :rolleyes:
  • No.8 | | 1727 bytes | |

    It may, but - on the other hand - it doesn't have to. Let me try:SQL> create table hours_cum
    2 (person number,
    3 days number,
    4 hours_worked number,
    5 cumulative number);

    Table created.

    SQL> CREATE OR REPLACE TRIGGER trg_hours
    2 BEFORE INSERT ON HOURS_CUM
    3 FOR EACH ROW
    4 BEGIN
    5 SELECT
    6 NVL(MAX(t.days) + 1, 1),
    7 NVL(SUM(t.HOURS_worked), 0) + :NEW.HOURS_worked
    8 INTO :NEW.days, :NEW.cumulative
    9 FROM HOURS_CUM t
    10 WHERE person = :NEW.person;
    11 END;
    12 /

    Trigger created.

    SQL> insert into hours_cum (person, hours_worked) values (1, 8);

    1 row created.

    SQL> select * from hours_cum;

    PERSON DAYS HOURS_WORKED CUMULATIVE
    ---- ---- ---- ----
    1 1 8 8

    SQL> insert into hours_cum (person, hours_worked) values (1, 7);

    1 row created.

    SQL> select * from hours_cum;

    PERSON DAYS HOURS_WORKED CUMULATIVE
    ---- ---- ---- ----
    1 1 8 8
    1 2 7 15

    SQL> insert into hours_cum (person, hours_worked) values (2, 5);

    1 row created.

    SQL> select * from hours_cum;

    PERSON DAYS HOURS_WORKED CUMULATIVE
    ---- ---- ---- ----
    1 1 8 8
    1 2 7 15
    2 1 5 5

    SQL>It seems quite OK to me ... did you have something else in mind, what I don't see at the moment?
  • No.9 | | 677 bytes | |

    In summary, there's not much difference between the "trigger" solution and the "view" solution -- i.e., you insert into the first three columns, and you may read the four columns.
    Advantages of the "trigger" solution:
    - only need one table in all SQL
    - 4th column is calculated once, and stored; no recalculation on read
    Advantages of the "view" solution:
    - less danger of attempt to insert into 4th column, since the table to be inserted only has 3 columns, and an attempt to insert into the view will tell you it's a view
    - a trigger is invisible for SQL; with the view it is clearer for the SQL user that the 4th column is a calculated one.
  • No.10 | | 242 bytes | |

    For what it's worth, I would prefer the view-method. Next to the advantages Peter summarized it complies with the first normalform to!

    BTW: Did anyone notice the initial asker, Divardo, never replied to this thread?

    Bye
  • No.11 | | 45 bytes | |

    Never mind; we had a nice little chat here :)

Re: Cumulative Field


max 4000 letters.
Your nickname that display:
In order to stop the spam: 8 + 7 =
QUESTION ON "ANSI SQL"

DATABASE TECH