Thread: Re: [NOVICE] aggregate function ?

Re: [NOVICE] aggregate function ?

From
coder@montx.com
Date:
hello again,

well, now it's faster, maybe it was the internet ...

Now it took only 6 seconds for 3217 rows through internet, great time, but the value of the sume is wrong ...


86067;"registro prop. barcelona";0.00;3.01;-9000.00
86069;"reg.mercantil barcelona (maribel)";0.00;9.00;-9000.00
86071;"reg.mercantil barcelona (maribel)";0.00;3.00;-9000.00
86073;"reg.mercantil barcelona (maribel)";0.00;7.50;-9000.00
86075;"reg.mercantil barcelona (maribel)";0.00;29.45;-9000.00
86089;"mensajeria 19/11-21/11/02 Maribel";0.00;44.43;-9000.00
86092;"mensajeria 24/12-03/12/02 Maribel";0.00;153.11;-9000.00
...


SELECT SUM( COALESCE( A3.deure ) - COALESCE ( A3.haver ) )
                       FROM Assentaments A3
                      WHERE A3.clau_compte = '0257000000002'
                        AND A3.data BETWEEN '2006-01-01' AND '2006-06-30'

This select returns this: -9000.00, so the number is ok.


thanks again, really !


rai




----- Original Message -----
From: Richard Broersma Jr
[mailto:rabroersma@yahoo.com]
To: coder@montx.com,
pgsql-novice@postgresql.org
Sent: Fri, 18 May 2007 21:06:02 +0200
Subject:
Re: [NOVICE] aggregate function  ?


> I found the typo in the query: by the way, it seems my version of postgresql
> is more verbose with
> it error message than yours.
> ...
> ERROR:  missing FROM-clause entry in subquery for table "a1"
> LINE 5:                         AND A1.data BETWEEN '2006-01-01' AND...
> ...
>
> anyway here is the correction:
>
>
> SELECT oid, concepte, deure, haver,
>        delta_sum + ( SELECT SUM( COALESCE( A3.deure ) - COALESCE ( A3.haver
> ) )
>                        FROM Assentaments A3
>                       WHERE A3.clau_compte = '0257000000002'
>                         AND A3.data BETWEEN '2006-01-01' AND '2006-06-30' )
> AS starting_Sum
> --This was A1 but should be A3^
>   FROM( SELECT A1.oid, A1.concepte, A1.deure, A1.haver,
>                sum( COALESCE( A2.deure, 0 ) -
>                     COALESCE( A2.haver, 0 )) AS value_sum
>           FROM Assentaments AS A1
>     INNER JOIN Assentaments AS A2
>             ON A1.oid >= A2.oid
>            AND A1.numero = A2.numero
>          WHERE A1.clau_compte = '0257000000002'
>       GROUP BY A1.oid, A1.concepte, A1.deure, A1.haver
>       ORDER BY A1.oid ) AS Summed_Assentaments( oid, concepte, deure, haver,
> delta_sum );
>
> >
> > and here comes the error:
> >
> > ERROR: missing FROM-clause entry in subquery for table "a1"
> > estat SQL: 42P01
> > Caràcter: 254
> >
> >
> > I can send you in a private e-mail some rows in .txt if you want to try
> ...
> >
> > And no, there's no relation between numero and compte in my table, I used
> numero because for me
> > it was easier to use only one field that use one with to options, data and
> between, but the code
> > should look like it's now.
> >
> > Sorry for the inconvenience ...
> >
> >
> >
> > thanks again !
> >
> >
> >
> >
> >
> >
> > ----- Original Message -----
> > From: Richard Broersma Jr
> > [mailto:rabroersma@yahoo.com]
> > To: coder@montx.com,
> > pgsql-novice@postgresql.org
> > Sent: Fri, 18 May 2007 19:47:11 +0200
> > Subject:
> > Re: [NOVICE] aggregate function  ?
> >
> >
> > >
> > > --- coder@montx.com wrote:
> > > >
> > > > ERROR: missing FROM-clause entry in subquery for table "a1"
> > > > estat SQL: 42P01
> > > > Caràcter: 254
> > > >
> > > >
> > > > This line ' WHERE A1.numero=11189 ' must change as this:
> > > >
> > > > 'WHERE A1.compte='572000001'  as the values must be from the same
> 'compte'
> > >
> > > Yes, it sounds like there is a relationship in your datamodel that I am
> not
> > > able to precieve
> > > across emails.  If there is a relationship between compte and numero,
> you
> > > should be able to
> > > connect this relationship up in the SQL select query.
> > >
> > > It is hard to know what the error is being produced by. can you send the
> > > actual query that you are
> > > posting and it resulting error message.
> > > Regards,
> > > Richard
> > >
> > > ---------------------------(end of broadcast)---------------------------
> > > TIP 1: if posting/reading through Usenet, please send an appropriate
> > >        subscribe-nomail command to majordomo@postgresql.org so that your
> > >        message can get through to the mailing list cleanly
> > >
> >
>
>
> ---------------------------(end of broadcast)---------------------------
> TIP 5: don't forget to increase your free space map settings
>

Re: aggregate function ?

From
Raimon Fernandez
Date:
Hello again,


Well, now it's working ...

SELECT oid, concepte, deure, haver,
        delta_sum + ( SELECT SUM( COALESCE( A3.deure ) - COALESCE
( A3.haver ) )
                        FROM Assentaments A3
                       WHERE A3.clau_compte = '0257000000002'
                         AND A3.data BETWEEN '2006-01-01' AND
'2006-06-30' ) AS starting_Sum
   FROM( SELECT A1.oid, A1.concepte, A1.deure, A1.haver,
                sum( COALESCE( A2.deure, 0 ) -
                     COALESCE( A2.haver, 0 )) AS value_sum
           FROM Assentaments AS A1
     INNER JOIN Assentaments AS A2
             ON A1.oid >= A2.oid
            AND A1. clau_compte = A2. clau_compte -- this was
A1.numero=A2.numero but should be Ax.clau_compte
          WHERE A1.clau_compte = '0257000000002'
       GROUP BY A1.oid, A1.concepte, A1.deure, A1.haver
       ORDER BY A1.oid ) AS Summed_Assentaments( oid, concepte,
deure, haver, delta_sum );

This returns 3217 rows, and the value_sum is ok, but it takes too
long (89.45 sec)

Can anyone confirm that it's doing for every row the
'starting_sum' (first select), and if so, how to do it just once ?


Here is the explain:
---------------------------------------------------------
Subquery Scan summed_assentaments  (cost=39706774.23..39784540.01
rows=3941 width=96)
   InitPlan
     ->  Aggregate  (cost=259.83..259.84 rows=1 width=28)
           ->  Bitmap Heap Scan on assentaments a3
(cost=181.43..259.78 rows=20 width=28)
                 Recheck Cond: ((data >= '2006-01-01'::date) AND
(data <= '2006-06-30'::date) AND (clau_compte =
'0257000000002'::bpchar))
                 ->  BitmapAnd  (cost=181.43..181.43 rows=20 width=0)
                       ->  Bitmap Index Scan on data
(cost=0.00..75.48 rows=3941 width=0)
                             Index Cond: ((data >=
'2006-01-01'::date) AND (data <= '2006-06-30'::date))
                       ->  Bitmap Index Scan on clau_compte
(cost=0.00..105.70 rows=3941 width=0)
                             Index Cond: (clau_compte =
'0257000000002'::bpchar)
   ->  GroupAggregate  (cost=39706514.39..39784230.90 rows=3941
width=92)
         ->  Sort  (cost=39706514.39..39719457.29 rows=5177160 width=92)
               Sort Key: a1.oid, a1.concepte, a1.deure, a1.haver
               ->  Nested Loop  (cost=105.70..38067432.51
rows=5177160 width=92)
                     Join Filter: (a1.oid >= a2.oid)
                     ->  Index Scan using clau_compte on assentaments
a1  (cost=0.00..14345.11 rows=3941 width=120)
                           Index Cond: (clau_compte =
'0257000000002'::bpchar)
                     ->  Bitmap Heap Scan on assentaments a2
(cost=105.70..9606.43 rows=3941 width=88)
                           Recheck Cond: ('0257000000002'::bpchar =
clau_compte)
                           ->  Bitmap Index Scan on clau_compte
(cost=0.00..105.70 rows=3941 width=0)
                                 Index Cond: ('0257000000002'::bpchar
= clau_compte)


thanks in advance!


regards,


raimon



Re: aggregate function ?

From
Richard Broersma Jr
Date:
--- Raimon Fernandez <coder@montx.com> wrote:
> This returns 3217 rows, and the value_sum is ok, but it takes too
> long (89.45 sec)
>
> Can anyone confirm that it's doing for every row the
> 'starting_sum' (first select), and if so, how to do it just once ?

Yes, any sub-select in the Select expression list will be executed many times. To fix this, you
will need to reform your query by pushing this sub-select down to the from clause.  Also you will
need to add clau_compte to the SELECT expression list of both sub-Selects

    SELECT <your expression list>, Summed_assentaments.delta_sum + Initialvalue.starting_sum
      FROM ( <your first initial sub-select> ) AS Summed_Assentaments( oid, concepte,deure, haver,
delta_sum, clau_compte )
INNER JOIN ( <your initial value sub-select> ) AS Initialvalue( starting_sum, clau_compte )
        ON Summed_Assentaments.clau_compte = Initialvalue.clau_compte;

I hope this can help to improve query time.

Regards,
Richard Broersma Jr.

Re: aggregate function ?

From
Raimon Fernandez
Date:
ok, thanks for the clarification ...

I'll try to do it myself and see ... but also I would like to do it
in a function/stored procedure, as will be more clear for me ...

and in this way I'll compare the speed difference ...

my initial approach is:

create temporary table test as SELECT
oid,numero,data,concepte,deure,haver,(deure-haver) as saldo FROM
assentaments WHERE clau_compte='0257000000002';

create a cursor,

loop for each row and update the saldo field

and return the select * from test

still working ...


regards and thanks again !


raimon




On 21/05/2007, at 14:46, Richard Broersma Jr wrote:

>
> --- Raimon Fernandez <coder@montx.com> wrote:
>> This returns 3217 rows, and the value_sum is ok, but it takes too
>> long (89.45 sec)
>>
>> Can anyone confirm that it's doing for every row the
>> 'starting_sum' (first select), and if so, how to do it just once ?
>
> Yes, any sub-select in the Select expression list will be executed
> many times. To fix this, you
> will need to reform your query by pushing this sub-select down to
> the from clause.  Also you will
> need to add clau_compte to the SELECT expression list of both sub-
> Selects
>
>     SELECT <your expression list>, Summed_assentaments.delta_sum +
> Initialvalue.starting_sum
>       FROM ( <your first initial sub-select> ) AS
> Summed_Assentaments( oid, concepte,deure, haver,
> delta_sum, clau_compte )
> INNER JOIN ( <your initial value sub-select> ) AS Initialvalue
> ( starting_sum, clau_compte )
>         ON Summed_Assentaments.clau_compte = Initialvalue.clau_compte;
>
> I hope this can help to improve query time.
>
> Regards,
> Richard Broersma Jr.
>