Обсуждение: caculating while select - maybe sum ?
Hi All im trying to calculate hour usage so a typical row is: 1. enter time, 2. exit time 3. sum() until this row Couldn't use sum() as it ask me to 'group by' which I don't want. Is there a way to add the previous row value to the current, per row ? example: select row1, row2, (row1 + row2 until now) from table; -------------------------- Canaan Surfing Ltd. Internet Service Providers Ben-Nes Michael - Manager Tel: 972-4-6991122 http://sites.canaan.co.il --------------------------
I'm not quite sure what you're asking for; but it shoulds like you want:
age(timestamp,timestamp) => interval
For example:
select age('2002-12-25',now());
age
--------------------------
10 mons 19 days 12:30:28
(1 row)
Frank
At 04:17 PM 2/5/02 +0200, Ben-Nes Michael wrote:
>Hi All
>
>im trying to calculate hour usage so a typical row is: 1. enter time, 2.
>exit time 3. sum() until this row
>
>Couldn't use sum() as it ask me to 'group by' which I don't want.
>
>Is there a way to add the previous row value to the current, per row ?
>
>example:
>select row1, row2, (row1 + row2 until now) from table;
>
>--------------------------
>Canaan Surfing Ltd.
>Internet Service Providers
>Ben-Nes Michael - Manager
>Tel: 972-4-6991122
>http://sites.canaan.co.il
>--------------------------
Nope, I mean:
a column from table:
1
2
7
4
select row1, sum (row1 until current row) from table;
Result:
1 | 1
2 | 3
7 | 10
4 | 14
the second column is like sum() of all the rows until/include this row.
Sorry for being ambigious
On Tuesday 05 February 2002 18:21, Frank Bax wrote:
> I'm not quite sure what you're asking for; but it shoulds like you want:
> age(timestamp,timestamp) => interval
> For example:
> select age('2002-12-25',now());
> age
> --------------------------
> 10 mons 19 days 12:30:28
> (1 row)
>
> Frank
>
> At 04:17 PM 2/5/02 +0200, Ben-Nes Michael wrote:
> >Hi All
> >
> >im trying to calculate hour usage so a typical row is: 1. enter time, 2.
> >exit time 3. sum() until this row
> >
> >Couldn't use sum() as it ask me to 'group by' which I don't want.
> >
> >Is there a way to add the previous row value to the current, per row ?
> >
> >example:
> >select row1, row2, (row1 + row2 until now) from table;
> >
> >--------------------------
> >Canaan Surfing Ltd.
> >Internet Service Providers
> >Ben-Nes Michael - Manager
> >Tel: 972-4-6991122
> >http://sites.canaan.co.il
> >--------------------------
> select row1, sum (row1 until current row) from table;
> the second column is like sum() of all the rows until/include this row.
"Until this row" is not very specific. I'll assume that you are assuming
a time ordering for the rows, so that you are really saying that you
want the aggregate of something up to (and including?) the current
something.
Here is a little example of how you might do that:
lockhart=# create table t1 (i int, b timestamp, e timestamp);
CREATE
lockhart=# insert into t1 values (1, 'now', timestamp 'now' + '1 sec');
(repeat three times, slowly...)
lockhart=# create function xsum(timestamp)
lockhart-# returns int as 'select cast(sum(i) as int)
lockhart-# from t1 where b <= $1;' language 'sql';
CREATE
lockhart=# select *, xsum(b) from t1;
i | b | e | xsum
---+------------------------+------------------------+------
1 | 2002-02-05 17:14:37+00 | 2002-02-05 17:14:38+00 | 1
1 | 2002-02-05 17:14:40+00 | 2002-02-05 17:14:41+00 | 2
1 | 2002-02-05 17:14:41+00 | 2002-02-05 17:14:42+00 | 3
1 | 2002-02-05 17:14:42+00 | 2002-02-05 17:14:43+00 | 4
(4 rows)
Or if you want to sum a difference of times, try
lockhart=# create function tsum(timestamp)
lockhart-# returns interval as 'select sum(e-b)
lockhart-# from t1 where b <= $1;' language 'sql';
CREATE
lockhart=# select *, tsum(b) from t1;
i | b | e | tsum
---+------------------------+------------------------+----------
1 | 2002-02-05 17:14:37+00 | 2002-02-05 17:14:38+00 | 00:00:01
1 | 2002-02-05 17:14:40+00 | 2002-02-05 17:14:41+00 | 00:00:02
1 | 2002-02-05 17:14:41+00 | 2002-02-05 17:14:42+00 | 00:00:03
1 | 2002-02-05 17:14:42+00 | 2002-02-05 17:14:43+00 | 00:00:04
(4 rows)
This is an expensive query! I'll bet you can recast your specification
to something simpler which doesn't require executing a subquery for
every row.
hth
- Thomas
... and if you want to ditch the function call, you can try something like this: lockhart=# select *, (select sum(e-b) from t1 where b <= x.b) from t1 x; i | b | e | ?column? ---+------------------------+------------------------+---------- 1 | 2002-02-05 17:14:37+00 | 2002-02-05 17:14:38+00 | 00:00:01 1 | 2002-02-05 17:14:40+00 | 2002-02-05 17:14:41+00 | 00:00:02 1 | 2002-02-05 17:14:41+00 | 2002-02-05 17:14:42+00 | 00:00:03 1 | 2002-02-05 17:14:42+00 | 2002-02-05 17:14:43+00 | 00:00:04 (4 rows)