Re: HELP: aggregating insert rule for multirow inserts. - Mailing list pgsql-sql

From Mikey
Subject Re: HELP: aggregating insert rule for multirow inserts.
Date
Msg-id 45caccdc050505003936efa435@mail.gmail.com
Whole thread Raw
In response to HELP: aggregating insert rule for multirow inserts.  (Mischa Sandberg <mischa.sandberg@telus.net>)
Responses Re: HELP: aggregating insert rule for multirow inserts.
List pgsql-sql
What about this as a rule.  It seems to work for me.

create or replace rule critter_counter as
on INSERT to critter do (
 insert into zoostats     select distinct new.legs     where new.legs not in (select legs from zoostats);
      update zoostats set headcount = (              select count(*)              from critter              where
critter.legs= zoostats.legs      ) where zoostats.legs = new.legs 
);

===============
OUTPUT (from entire script)
===============
CREATE TABLE
psql:pglist-problem.1.sql:4: NOTICE:  CREATE TABLE / PRIMARY KEY will
create implicit index 'zoostats_pkey' for table 'zoostats'
CREATE TABLE
CREATE RULE
INSERT 17347 1
INSERT 17349 1
INSERT 17351 1
INSERT 17353 1 name   | legs
----------+------
cat      |    4
starfish |    5
ant      |    6
dog      |    4
(4 rows)

legs | headcount
------+-----------  5 |         1  6 |         1  4 |         2
(3 rows)

INSERT 0 4
legs | headcount
------+-----------  4 |         4  5 |         2  6 |         2
(3 rows)

psql:pglist-problem.1.sql:32: NOTICE:  Drop cascades to rule
critter_counter on table critter
DROP TABLE
DROP TABLE
=========
End OUTPUT
=========

(oops forgot to send to list)
--Mike

On 5/4/05, Mischa Sandberg <mischa.sandberg@telus.net> wrote:
> I'm having a problem with the use of the NEW rowset,
> in a rule intended to aggregate across inserts.
>
> I've never really grokked how NEW and OLD really work,
> syntactically, other than that they seem to be implicit
> in every top-level FROM clause, and any mention elsewhere
> gets an error: '42P01: relation "*NEW*" does not exist'.
>
> I've tried different flavours of the UPDATE command,
> in the following rule, and they either produce syntax errors
> or the wrong results.
>
> Any suggestions much appreciated ...
>
> ====================== CODE
> "How many critters are in the zoo, of the 4,5,6...-legged varieties?"
>
> create table critter(name text, legs int);
> create table zoostats(legs int, headcount int default 0,
>                       primary key(legs));
>
> create or replace rule critter_counter as
> on INSERT to critter do (
>
>     insert into zoostats
>         select distinct new.legs
>         where new.legs not in (select legs from zoostats);
>
>     update zoostats
>     set    headcount = headcount + (select count(*)) -- "from new"
>     where new.legs = zoostats.legs
> );
>
> insert into critter values('cat',4);
> insert into critter values('starfish',5);
> insert into critter values('ant',6);
> insert into critter values('dog',4);
>
> insert into critter select * from critter; -- double everything.
>
> select * from zoostats;
>
> drop table zoostats cascade;
> drop table critter;
> ====================== EXPECTED OUTPUT
> legs headcount
> ---- ---------
>    4         4
>    5         2
>    6         2
> ====================== ACTUAL OUTPUT
> legs headcount
> ---- ---------
>    4         3      -- !?
>    5         2
>    6         2
> ====================== OTHER ATTEMPT:
> This version of the update looks syntactically right to me,
> but makes CREATE RULE fail on a syntax error:
>
>  ...
>
> update zoostats
> set headcount = headcount + tally
> from (select new.legs, count(new.legs) as tally -- from new !?
>         group by new.legs) as poll
> where poll.legs = zoostats.legs;
>
> ERROR: 'Subquery in FROM may not refer to other relations
>         of same query level'.
> --
> Engineers think equations approximate reality.
> Physicists think reality approximates the equations.
> Mathematicians never make the connection.
>
> ---------------------------(end of broadcast)---------------------------
> TIP 3: 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
>


--
Time is my Nemesis!
But, if I stopped time for one year,
how would I know when that year was finished?...


pgsql-sql by date:

Previous
From: Richard Huxton
Date:
Subject: Re: accessing multiple database
Next
From: "mohammad izwan ibrahim"
Date:
Subject: Re: accessing multiple database