AdvancedTopic: MajStore_PostGis_refactored.sql

File MajStore_PostGis_refactored.sql, 7.6 KB (added by 231049, 3 days ago)
Line 
1CREATE EXTENSION IF NOT EXISTS postgis;
2
3alter table location add column geom GEOMETRY(Point, 4326);
4update location set geom = ST_SetSRID(ST_MakePoint(longitude, latitude), 4326);
5
6create index idx_location_geom on Location USING GIST(geom);
7
8
9
10-- WORKER
11-- 1
12create or replace function fn_v2_suggest_posts_for_worker(p_worker_id int, p_limit int default 10)
13 returns table (post_id int, title text, distance_meters float, location_id int, post_address text, post_region text, post_city text)
14 language plpgsql
15as $$
16declare
17 v_works_remote bool;
18begin
19 select w.works_remote
20 into v_works_remote
21 from worker w
22 where w.worker_id = p_worker_id;
23
24 return query
25 select p.post_id,
26 p.title,
27 ST_Distance(worker_loc.geom::geography, post_loc.geom::geography)::float as distance_meters,
28 post_loc.location_id,
29 post_loc.address,
30 post_loc.region,
31 post_loc.city
32 from worker w
33 join location worker_loc on w.location_id = worker_loc.location_id
34 join post p on p.status_id = 1
35 join location post_loc on p.location_id = post_loc.location_id
36 where w.worker_id = p_worker_id
37 and exists(select 1
38 from worker_specialty ws
39 join post_specialty ps on ws.specialty_id = ps.specialty_id
40 where ws.worker_id = w.worker_id and ps.post_id = p.post_id)
41 and (v_works_remote = true or ST_DWithin(worker_loc.geom::geography, post_loc.geom::geography, 1500))
42 and p.status_id = 1
43 order by worker_loc.geom <-> post_loc.geom
44 limit p_limit;
45end;
46$$;
47
48select * from fn_v2_suggest_posts_for_worker(6630361, 10);
49select * from fn_v2_suggest_posts_for_worker(6630362, 10000);
50
51
52
53
54
55-- 2
56create or replace function fn_v2_draw_worker_location(p_worker_id integer)
57 returns table(worker_id integer, geom geometry)
58 language plpgsql
59as $$
60begin
61 return query
62 select
63 w.worker_id,
64 l.geom
65 from worker w
66 join location l on w.location_id = l.location_id
67 where w.worker_id = p_worker_id;
68end;
69$$;
70
71select * from fn_v2_draw_worker_location(6630361);
72select * from fn_v2_draw_worker_location(6630362);
73
74
75
76
77
78
79-- 3
80create or replace function fn_v2_draw_active_posts_in_worker_region(p_worker_id integer, p_limit int default 10)
81 returns table(post_id integer, distance_meters float, geom geometry)
82 language plpgsql
83as $$
84begin
85 return query
86 select p.post_id, p.distance_meters, post_loc.geom
87 from fn_v2_suggest_posts_for_worker(p_worker_id, p_limit) p
88 join location post_loc on post_loc.location_id = p.location_id;
89end;
90$$;
91
92select * from fn_v2_draw_active_posts_in_worker_region(6630361);
93select * from fn_v2_draw_active_posts_in_worker_region(6630362);
94
95
96
97
98
99
100
101-- 4
102create or replace function fn_v2_draw_worker_to_post_lines(p_worker_id integer, p_limit int default 10)
103 returns table(post_id integer, title text, distance_m float, geom geometry)
104 language plpgsql
105as $$
106declare
107 v_worker_geom geometry;
108begin
109 select l.geom
110 into v_worker_geom
111 from worker w
112 join location l on w.location_id = l.location_id
113 where w.worker_id = p_worker_id;
114
115 return query
116 select
117 p.post_id,
118 p.title,
119 p.distance_meters,
120 ST_MakeLine(v_worker_geom, post_loc.geom) as geom
121 from fn_v2_suggest_posts_for_worker(p_worker_id, p_limit) p
122 join location post_loc on post_loc.location_id = p.location_id;
123end;
124$$;
125
126select * from fn_v2_draw_worker_to_post_lines(6630361);
127select * from fn_v2_draw_worker_to_post_lines(6630362);
128
129
130
131
132
133-- 5
134create or replace function fn_v2_draw_worker_notRemote_region(p_worker_id integer)
135 returns table(worker_id integer, geom geometry)
136 language plpgsql
137as $$
138declare
139 v_works_remote bool;
140begin
141 select w.works_remote into v_works_remote
142 from worker w
143 where w.worker_id = p_worker_id;
144
145 if v_works_remote = true then
146 return;
147 end if;
148
149 return query
150 select
151 w.worker_id,
152 ST_Buffer(l.geom::geography, 1000)::geometry as geom
153 from worker w
154 join location l on w.location_id = l.location_id
155 where w.worker_id = p_worker_id;
156end;
157$$;
158
159select * from fn_v2_draw_worker_notRemote_region(6630361);
160select * from fn_v2_draw_worker_notRemote_region(6630362);
161
162
163
164
165
166
167
168
169-- POSTS
170-- 6
171drop function fn_v2_application_workers_for_post
172create or replace function fn_v2_application_workers_for_post(p_post_id int, p_limit int default 10)
173 returns table(worker_id int, first_name text, last_name text, message text, expected_price float, distance_meters float, location_id int, worker_address text, wokrer_region text, worker_city text)
174 language plpgsql
175as $$
176begin
177 return query
178 select w.worker_id,
179 u.first_name,
180 u.last_name,
181 a.message,
182 a.expected_price,
183 ST_Distance(worker_loc.geom::geography, post_loc.geom::geography)::float as distance_meters,
184 worker_loc.location_id,
185 worker_loc.address,
186 worker_loc.region,
187 worker_loc.city
188 from worker w
189 join "User" u on w.user_id = u.user_id
190 join location worker_loc on w.location_id = worker_loc.location_id
191 join post p on p.post_id = p_post_id
192 join application a on p.post_id = a.post_id and a.worker_id = w.worker_id
193 join location post_loc on p.location_id = post_loc.location_id
194 where (w.works_remote = true
195 or ST_DWithin(worker_loc.geom::geography, post_loc.geom::geography, 1500))
196 and p.status_id = 1
197 order by worker_loc.geom <-> post_loc.geom
198 limit p_limit;
199end;
200$$;
201
202select * from fn_v2_application_workers_for_post(1787990);
203
204
205
206
207
208-- 7
209create or replace function fn_v2_draw_post_location(p_post_id integer)
210 returns table(post_id integer, title text, geom geometry)
211 language plpgsql
212as $$
213begin
214 return query
215 select
216 p.post_id,
217 p.title,
218 l.geom
219 from post p
220 join location l on p.location_id = l.location_id
221 where p.post_id = p_post_id;
222end;
223$$;
224
225select * from fn_v2_draw_post_location(1787990);
226
227
228
229
230
231
232
233-- 8
234create or replace function fn_v2_draw_workers_applied_to_post(p_post_id integer, p_limit int default 10)
235 returns table(worker_id integer, distance_m float, geom geometry)
236 language plpgsql
237as $$
238declare
239 v_post_geom geometry;
240begin
241 select p.geom
242 into v_post_geom
243 from fn_draw_post_location(p_post_id) p;
244
245 return query
246 select
247 w.worker_id,
248 ST_Distance(v_post_geom::geography, worker_loc.geom::geography)::float as distance_m,
249 worker_loc.geom as geom
250 from application a
251 join worker w on w.worker_id = a.worker_id
252 join location worker_loc on w.location_id = worker_loc.location_id
253 where a.post_id = p_post_id
254 order by v_post_geom <-> worker_loc.geom
255 limit p_limit;
256end;
257$$;
258
259select * from fn_v2_draw_workers_applied_to_post(1787990);
260
261
262
263
264
265
266-- 9
267create or replace function fn_v2_draw_post_to_applicant_lines(p_post_id integer, p_limit int default 10)
268 returns table(worker_id integer, distance_m float, geom geometry)
269 language plpgsql
270as $$
271declare
272 v_post_geom geometry;
273begin
274 select p.geom
275 into v_post_geom
276 from fn_draw_post_location(p_post_id) p;
277
278 return query
279 select
280 w.worker_id,
281 w.distance_m,
282 ST_MakeLine(v_post_geom, w.geom) as geom
283 from fn_draw_workers_applied_to_post(p_post_id, p_limit) w;
284end;
285$$;
286
287select * from fn_v2_draw_post_to_applicant_lines(1787990);