Re: select count of all overlapping geometries and return 0 if none. - Mailing list pgsql-sql

From Steve Midgley
Subject Re: select count of all overlapping geometries and return 0 if none.
Date
Msg-id 20090313173255.C251F63246F@mail.postgresql.org
Whole thread Raw
List pgsql-sql
At 06:20 AM 3/13/2009, pgsql-sql-owner@postgresql.org wrote:
>Message-ID: <457532.70947.qm@web45913.mail.sp1.yahoo.com>
>Date: Thu, 12 Mar 2009 10:28:19 -0700 (PDT)
>From: Duffer Do <dufferdo25@yahoo.com>
>Subject: select count of all overlapping geometries and return 0 if 
>none.
>To: pgsql-sql@postgresql.org
>X-Archive-Number: 200903/24
>X-Sequence-Number: 32267
>
>Hello all,
>I have 2 tables locations and user_tracker:
>
>locations has 2 columns
>location_name
>location_geometry
>
>user_tracker has 3 columns
>user_name
>user_geometry
>user_timestamp
>
>
>locations table is coordinates and names of areas of interest.
>user_tracker basically is an archive of a user's movements as he pans 
>his map.
>
>I have a need to assign a ranking of locations based on how many times 
>users have intersected this location.
>
>The problem I am having is that my query only returns locations that 
>have been intersected by a user.
>I need it to return ALL locations and a zero if this location has not 
>been intersected.
>
>As an example:
>
>LOCATIONS
>1: Talahassee, FL | talahassee's bounding box
>2: Manhattan, NY  | Manhattan's bounding box
>3: Frankfurt, GE    | Frankfurt's bounding box
>
>
>USER_TRACKER
>john doe     | geometry that overlaps Frankfurt  | today
>john doe     | geometry that overlaps Frankfurt  | today
>john doe     | geometry that overlaps Frankfurt  | today
>john doe     | geometry that overlaps Frankfurt  | yesterday
>john doe     | geometry that overlaps Frankfurt  | Monday
>john doe     | geometry that overlaps Frankfurt  | Sunday
>Mary Jane  | geometry that overlaps Manhattan  | today
>Rob Roy    | geometry that overlaps Manhattan  | today
>Rob Roy    | geometry that overlaps Manhattan  | today
>
>
>I want to return the following:
>locations    |  number_visits
>Frankfurt    |  6
>Manhattan  |  3
>Talahassee |  0
>
>My query only returns:
>Frankfurt    |  6
>Manhattan  | 3
>
>Now I have really simplified this example for readability, my actual 
>tables are more complex.
>
>How can I accomplish this?
>
>My query:
>SELECT count(user_name) as number_visits, location_name from 
>locations, user_tracker WHERE user_geometry && location_geometry
>
>Thanks in advance

Hi,

I am stuck at an airport right now, and had the time to hack out your 
solution. I hope it helps. In the future, it would be helpful to the 
list (and more likely to yield responses) if you include the 
create/insert statements such as what I've put together below. It makes 
it much easier for people to quickly get you an answer - in this case I 
had a spare 20 minutes so I did it for you.

Also, I put a gist index on your locations table but that assumes your 
areas are flat, which isn't right for spherical coordinates on the 
earth. PostGis should be able to get you closer, if that kind of 
accuracy matters.

Anyway, here are the table setups and what I believe is the solution 
query:


-- START SQL SCRIPT --

drop table if exists locations;
create table locations
(id serial,
name varchar(255),
area circle);

insert into locations (name, area)
values
('Talahassee, FL','((0,0),1)'),
('Manhattan, NY','((2,0),1)'),
('Frankfurt, GE','((4,0),1)');

CREATE INDEX idx_locations_area ON locations USING gist ("area");

drop table if exists user_tracker;
create table user_tracker
(id serial primary key,
name varchar(255),
location point,
time varchar(255));

insert into user_tracker (name,location,time)
values
('john doe', '(4,0)', 'today'),
('john doe', '(4,0)', 'today'),
('john doe', '(4,0)', 'today'),
('john doe', '(4,0)', 'yesterday'),
('john doe', '(4,0)', 'Monday'),
('john doe', '(4,0)', 'Sunday'),
('Mary Jane', '(2,0)', 'today'),
('Rob Roy', '(2,0)', 'today'),
('Rob Roy', '(2,0)', 'today');


-- SOLUTION QUERY HERE --
select count(user_tracker.id), locations.name from user_tracker
right outer join locations on user_tracker.location <@ locations.area
group by locations.name;


-- END SQL SCRIPT --

OUTPUT:

>3;"Manhattan, NY"
>0;"Talahassee, FL"
>6;"Frankfurt, GE"

Steve 



pgsql-sql by date:

Previous
From: "seb JACK"
Date:
Subject: RE : [SQL] Convert text from UTF8 to ASCII
Next
From: Mina R Waheeb
Date:
Subject: Re: Permanent alias for postgresql table