0
-- trigger function
CREATE OR REPLACE FUNCTION fn_cities_geo_update_event() RETURNS trigger AS $fn_cities_geo_update_event$
  BEGIN

is it ok to set a value (geog) which will be used later in the function?

    NEW.geog := ST_SetSRID(ST_MakePoint(NEW.longitude,NEW.latitude), 4326)::geography;

this is one way that I tried to find the average of all cities within 90km of a new city so that the new city will have data populated about it

  if NEW.rent_avg IS null then
    NEW.rent_avg = (
      SELECT avg(a.rent_avg)
      FROM cities as a
-- I think I'm missing something here... ?
      ST_DWithin(a.geog, NEW.geog, 90000)
      );
  end if;

here is another way that I tried:

  if NEW.food_avg IS null then
  NEW.food_avg := (
    SELECT avg(a.food_avg)
    FROM    cities AS a
    JOIN    NEW AS b
      ON    ST_DWithin(a.geog, b.geog, 90000)
    );
  end if;
  RETURN NEW;
  END;
$fn_cities_geo_update_event$ LANGUAGE plpgsql;

but neither worked.

edit: here is a copy of the table that I'm working with

l    |u |n                         |population|unesco|r                        |c               |rent_avg|rent_low|rent_high|food_avg|food_low|food_high|transport_avg|transport_low|transport_high|k        |i  |quality|hcid                                 |hc  |latitude   |longitude |spread     |density   |distance  |dbn                       |state|geog                                              |id   
-----|--|--------------------------|----------|------|-------------------------|----------------|--------|--------|---------|--------|--------|---------|-------------|-------------|--------------|---------|---|-------|-------------------------------------|----|-----------|----------|-----------|----------|----------|--------------------------|-----|--------------------------------------------------|-----
false|NZ|Gisborne                  |     34274|     0|Australia and New Zealand|New Zealand     | 92.2430| 51.1720| 143.4150| 22.0300| 13.3190|  35.3490|       7.0650|       5.9800|       13.0450|4VHV8X00+|GIS|   1712|place:Gisborne                       |  46|-38.6640015|177.977005| 0.99940002|         0|          |                          |     |0101000020E6100000000000A0433F664000000000FE5443C0| 1611
true |NZ|Patutahi                  |       386|      |Australia and New Zealand|New Zealand     |        |        |         |        |        |         |             |             |              |4VHV9V00+|   |   1000|place:Patutahi                       |  35|-38.6170006|177.899994|           |          |       8.5|Patutahi                  |     |0101000020E6100000000000C0CC3C6640000000E0F94E43C0| 1624
true |NZ|Waihau Bay                |          |      |Australia and New Zealand|New Zealand     |        |        |         |        |        |         |             |             |              |4VJV8Q00+|   |   1000|place:Waihau_Bay                     |   6|-37.6780014|177.796005|           |          |110.699997|Waihau Bay                |     |0101000020E6100000000000E078396640000000C0C8D642C0| 1671
true |NZ|Tokomaru Bay              |       495|      |Australia and New Zealand|New Zealand     |        |        |         |        |        |         |             |             |              |4VHWV800+|   |   1000|place:Tokomaru_Bay                   |   5|-38.1329994|178.300003|           |          |65.4000015|Tokomaru Bay              |     |0101000020E6100000000000A09949664000000020061143C0| 1673
true |FR|Cornebarrieu              |          |      |Western Europe           |France          |        |        |         |        |        |         |             |             |              |8FM3M800+|   |   1000|place:Cornebarrieu                   | 112| 43.6559982|1.33299994| 3.60581994|          | 3.5999999|Cornebarrieu              |     |0101000020E6100000000000C0F753F53F000000C0F7D34540| 6070

edit: create trigger statement

DROP TRIGGER IF EXISTS tr_cities_inserted ON cities;
CREATE TRIGGER tr_cities_inserted
  BEFORE INSERT ON cities
  FOR EACH ROW
  EXECUTE PROCEDURE fn_cities_geo_update_event();
11
  • No. NEW is a data type record. it represents a row :D postgresql.org/docs/9.2/plpgsql-trigger.html Commented Feb 12, 2019 at 6:10
  • Oh shit, it's a trigger XD sry I got carried away. Let me delete that. Commented Feb 12, 2019 at 6:13
  • it's ok :) I'm trying to understand this also. Yes the first line I'm trying to create the geog column for a single row Commented Feb 12, 2019 at 6:15
  • I'm new to postgers, too, but I like PostGIS. Can you add to your question the first two to three lines of the table, the trigger is for? Commented Feb 12, 2019 at 6:25
  • sure! I've edited the post Commented Feb 12, 2019 at 6:35

1 Answer 1

1

Okay, this is interesting.. I am new to triggers (as you may have noticed ^^) so it seems, when I recreate a table AFTER I created a trigger for that table, the trigger doesn't work. It just returns null for the respective columns.

When I stick to the proper order, I get it to work with my sample reproduction of your case:

CREATE TABLE so_postgres
(n text,
 r text,
 c text,
 rent_avg numeric,
 food_avg numeric,
 transport_avg numeric,
 latitude numeric,
 longitude numeric,
 geog geography
 );

 INSERT INTO so_postgres
 VALUES  ('Möhringen', 'central europe', 'germany', 200.45, 56.45, 4.56, 48.725866, 
           9.146131, ST_SetSRID(ST_Point(9.146131, 48.725866), 4326)),
         ('Vaihingen', 'central europe', 'germany', 155.33, 44.12, 2.78, 48.732550,
           9.108291, ST_SetSRID(ST_Point(9.108291, 48.732550), 4326)),
         ('Sigmaringen', 'central europe', 'germany', 298.11, 59.67, 1.99, 48.090797, 
           9.230243, ST_SetSRID(ST_Point(9.230243, 48.090797), 4326));

CREATE OR REPLACE FUNCTION fn_cities_geo_update_event() RETURNS trigger AS $fn_cities_geo_update_event$


BEGIN


NEW.geog := (ST_SetSRID(ST_MakePoint(NEW.longitude,NEW.latitude), 4326)::geography);

  if NEW.rent_avg IS null then
    NEW.rent_avg := (
      SELECT round(avg(a.rent_avg), 2)
      FROM so_postgres as a
      WHERE ST_DWithin(a.geog, NEW.geog, 50000)
      );
  end if;

 RETURN NEW;
  END;
$fn_cities_geo_update_event$ LANGUAGE plpgsql;


CREATE TRIGGER fn_cities_geo_update_event BEFORE INSERT OR UPDATE ON so_postgres FOR EACH ROW EXECUTE PROCEDURE fn_cities_geo_update_event();

 INSERT INTO so_postgres (n, r, c, latitude, longitude)
 VALUES ('Degerloch', 'central europe', 'germany', 48.725866, 9.146131); 

      n      |       r        |    c    | rent_avg | food_avg | transport_avg | latitude  | longitude |                        geog
-------------+----------------+---------+----------+----------+---------------+-----------+-----------+----------------------------------------------------
 Möhringen   | central europe | germany |   200.45 |    56.45 |          4.56 | 48.725866 |  9.146131 | 0101000020E610000012DDB3AED14A2240A1A3552DE95C4840
 Vaihingen   | central europe | germany |   155.33 |    44.12 |          2.78 | 48.732550 |  9.108291 | 0101000020E6100000FBE6FEEA71372240A857CA32C45D4840
 Sigmaringen | central europe | germany |   298.11 |    59.67 |          1.99 | 48.090797 |  9.230243 | 0101000020E61000000F441669E275224097C9703C9F0B4840
 Degerloch   | central europe | germany |   177.89 |          |               | 48.725866 |  9.146131 | 0101000020E610000012DDB3AED14A2240A1A3552DE95C4840

To answer your last comment: I add the ST_DWithin to the rest of the query via a WHERE-clause.

Does it work for you?

Sign up to request clarification or add additional context in comments.

2 Comments

Perfect! yes lol. I just needed a WHERE clause XD thank you for taking the time to work on this
I spotted the where thing in the beginning, but I didn't dare to think it might be this easy. Then I got distracted by my own error. xD But now there is a nice use case for people that are new to triggers. So it was worthwile I guess. ^^ Glad to help anyway

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.