Как рассчитать вещи из многих таблиц, используя несколько запросов? - PullRequest
0 голосов
/ 09 февраля 2012

примечание: этот вопрос относится к PostGIS и Postgresql и реализован с помощью PHP

Теперь у меня есть таблица A:

gid | kstart  | kend    | ctrl_sec_no | the_geom | 
626 | 238     | 239     | 120802      | 123456   |
638 | 249     | 250     | 120802      | 234567   |
4037| 239     | 249     | 120802      | 345678   |

примечание: the_geom является значением геометрии (TYPE: LINE), в этом случае я выбираю их случайным образом для удобства чтения

и таблицы B:

gid | ctrl_sec_no | x   | the_geom
543 | 120802      | 239 | null
544 | 120802      | 247 | null

[описание PostGIS] Эти две таблицы связаны ctrl_sec_no, что означает 3 непрерывных строки в ctrl_sec_no 120802 изТаблица A, соединена в одну ЛИНЕЙКУ и содержит две ТОЧКИ из Таблицы B. Мы знаем только расстояние {MAX (kend) - MIN (kstart)} ЛИНИИ и километр (x), где она находится в ЛИНИИ.

Вопрос в том, что представляет собой запрос PostgreSQL к ..

(a.) Выбрать наибольшее значение из A.kend, минус самое низкое значение из A.kstart -> 250 - 238 =12

(b.) Выберите самое высокое значение из A.kend, минус значение 'x' в B -> 250 - 239 = 11

(c.), Вычислите соотношение из этих двухзначение ((b.) / (a.)) -> 11/12

(d.) с использованием PostGIS: ST_Interpolate -> ST_Interpolate (A.the_geom, 11/12) примечание: эта функция используется длянайти ТОЧКУ вместе с ЛИНИЕЙ, с другой стороны, чтобы определить позицию, в которой ТОЧКА равна

(e.), мы получим значение из (d.) и используем его для ОБНОВЛЕНИЯ Таблицы B в 'the_geom'столбец, который изначально NULL.

(f.) Цикл этого набора запросов для каждой строки в таблице B.

[PostGIS Description] Цель этого набора запросов - определить the_geom в таблице B путем вычисления некоторой математикии поместите вывод в функцию ST_Interpolate, чтобы получить the_geom того, где находится ТОЧКА в Таблице B.

Спасибо в Advanced, я знаю, что это довольно сложный вопрос.Я не против, если вы будете использовать слишком много запросов.Просто чтобы получить правильное значение.

Это фактический запрос (окончательный) с помощью danihp.

with CTE( max_kend) as (
 SELECT MAX(A.kend)
 FROM centerline A
),
r_b as (
 select B.ctrl_sec_no,B.gid, MAX(CTE.max_kend) - B.km as b
  FROM land_inventory B cross join CTE group by B.gid,B.ctrl_sec_no,B.km
),
r_a as (
    SELECT MAX(A.kend) - MIN(A.kstart) as a
    FROM centerline A
),
r_ratio as (
  select r_b.gid, r_b.b / r_a.a  as my_ratio
  from r_a cross join r_b
),
r_new_int as (
select B.gid,r_ratio.my_ratio,B.ctrl_sec_no,B.km,ST_AsText(ST_Envelope(ST_Collect(ST_line_interpolate_point(A.the_geom,  r_ratio.my_ratio )))) as new_int from centerline A, land_inventory B inner join r_ratio on B.gid = r_ratio.gid where A.ctrl_sec_no = B.ctrl_sec_no group by B.ctrl_sec_no,B.gid,r_ratio.my_ratio,B.km order by B.ctrl_sec_no
) 
UPDATE land_inventory
set land_inventory.the_geom = n.new_int
from r_new_int n
where 
  n.gid = land_inventory.gid and
  land_inventory.the_geom is NULL;

1 Ответ

3 голосов
/ 09 февраля 2012

Хорошо, поехали.

(a)

SELECT MAX(A.kend) - MIN( A.kstart) as a
FROM Table A

(b)

EDITED Предполагая, что gid является PK для таблицы B ...

with CTE( max_kend, min_x) as (
 SELECT MAX(A.kend), NULL
 FROM TableA A
)
select B.gid, MAX(CTE.max_kend) - B.min_x as b
 FROM TableB B 
 cross join CTE

(c)

with CTE( max_kend, min_x) as (
 SELECT MAX(A.kend), NULL
 FROM TableA A
),
r_b as (
 select B.gid, MAX(CTE.max_kend) - B.min_x as b
  FROM TableB B 
  cross join CTE
),
r_a as (
    SELECT MAX(A.kend) - MIN( A.kstart) as a
    FROM Table A
)
select r_b.gid, r_a.a / r_b.b as my_ratio
from r_a cross join r_b

(d)

with CTE( max_kend, min_x) as (
 SELECT MAX(A.kend), NULL
 FROM TableA A
),
r_b as (
 select B.gid, MAX(CTE.max_kend) - B.min_x as b
  FROM TableB B 
  cross join CTE
),
r_a as (
    SELECT MAX(A.kend) - MIN( A.kstart) as a
    FROM Table A
),
r_ratio as (
  select r_b.gid, r_a.a / r_b.b as my_ratio
  from r_a cross join r_b
)
select ST_Interpolate(A.the_geom,  r_ratio.my_ratio )   
from TableB B 
inner join r_ratio on B.gid = r_ratio.gid

(e, f)

with CTE( max_kend, min_x) as (
 SELECT MAX(A.kend), NULL
 FROM TableA A
),
r_b as (
 select B.gid, MAX(CTE.max_kend) - B.min_x as b
  FROM TableB B 
  cross join CTE
),
r_a as (
    SELECT MAX(A.kend) - MIN( A.kstart) as a
    FROM Table A
),
r_ratio as (
  select r_b.gid, r_a.a / r_b.b as my_ratio
  from r_a cross join r_b
),
r_new_int as (
  select ST_Interpolate(A.the_geom,  r_ratio.my_ratio ) as new_int
  from TableB B 
  inner join r_ratio on B.gid = r_ratio.gid
)
UPDATE tableB
set tableB.the_geom = n.new_int
from r_new_int n
where 
  n.gid = tableB.gid and
  tableB.the_geom  is NULL

отказ от ответственности, а не тест.

РЕДАКТИРОВАНИЕ

with CTE( max_kend) as (
 SELECT MAX(A.kend)
 FROM centerline A
),
r_b as (
 select B.ctrl_sec_no,B.gid, MAX(CTE.max_kend) - B.km as b
  FROM land_inventory B cross join CTE group by B.gid,B.ctrl_sec_no,B.km
),
r_a as (
    SELECT MAX(A.kend) - MIN(A.kstart) as a
    FROM centerline A
),
r_ratio as (
  select r_b.gid, r_b.b / r_a.a  as my_ratio
  from r_a cross join r_b
),
r_new_int as (
  select     
    B.gid,
    r_ratio.my_ratio,
    B.ctrl_sec_no,B.km,
    ST_AsText(ST_Envelope(ST_Collect(
          ST_line_interpolate_point(A.the_geom,  r_ratio.my_ratio 
    )))) as new_int 
  from 
    centerline A inner join
    land_inventory B 
       on A.ctrl_sec_no = B.ctrl_sec_no 
       inner join 
    r_ratio on B.gid = r_ratio.gid 
  group by B.ctrl_sec_no,B.gid,r_ratio.my_ratio,B.km order by B.ctrl_sec_no
) 
UPDATE land_inventory
set the_geom = n.new_int
from r_new_int n
where 
  n.gid = land_inventory.gid and
  land_inventory.the_geom is NULL;
...