0

I have this table:

CREATE TABLE buildings (
    id SERIAL PRIMARY KEY UNIQUE,
    name character varying(20) NOT NULL UNIQUE,
    document jsonb
);

then this view:

CREATE VIEW v_rooms AS  
SELECT buildings.id AS building_id,
    buildings.name AS building_name,
((jsonb_array_elements(jsonb_array_elements(buildings.document -> 'levels'::text) -> 'rooms'::text) -> 'meta'::text) ->> 'sqft'::text)::numeric AS sqft
   FROM buildings
  GROUP BY buildings.id;

finally this view:

CREATE VIEW v_buildings AS  
SELECT buildings.id AS building_id,
    (buildings.document -> 'meta'::text) ->> 'name'::text AS name,
    sum(v_rooms.sqft) AS sqft
   FROM buildings,
    v_rooms
  GROUP BY buildings.id
  ORDER BY buildings.id;

All is well, except 'sqft' on v_buildings is returning the SUM of all the rows in v_rooms. I want to calculate SUM() where v_building.building_id == v_rooms.building_id.

2
  • I have tried SUM( v_rooms.sqft ) filter ( where v_rooms.building_id = building_id ) AS sqft still gives me the total of all rows. Commented Feb 20, 2020 at 9:53
  • yes but i want SUM of all v_rooms.sqft with the same building_id into v_buildings.sqft with the matching building_id. Commented Feb 21, 2020 at 6:32

1 Answer 1

3

Join to the aggregate, don't aggregate the join:

SELECT b.id AS building_id,
      (b.document -> 'meta'::text) ->> 'name'::text AS name,
      r.sqft
FROM buildings b
  JOIN (
   SELECT building_id, 
          sum(sqft) as sqft
   FROM v_rooms
   GROUP BY building_id
  ) r ON r.building_id = b.id;

Unrelated, but: although Postgres allows it, it's usually a bad idea to include an ORDER BY in a view definition.

1
  • works perfectly. thanks a a lot! Commented Feb 20, 2020 at 11:02

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.