Использование STIntersects для обновления таблицы - PullRequest
1 голос
/ 11 апреля 2019

У меня есть две таблицы с геометрическим столбцом:

  • Таблица t содержит деревья
  • Таблица ca содержит полигонизированные природоохранные территории.

Я пытаюсь использовать SQL Server и STIntersects, чтобы определить, когда некоторые деревья попадают в зону сохранения.

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

Решением может быть объединение всех полигонов в таблице областей консервации, но я предполагаю, что есть лучший способ решить эту проблему.

UPDATE [TREES]
SET 
  IN_CONSERVATION_AREA = 
    CASE
      WHEN 
        t.[geom].STIntersects(ca.[geom]) = 1 THEN 'Y'
      WHEN
        t.[geom].STIntersects(ca.[geom]) = 0 THEN 'N'
     END

FROM [CONSERVATION_AREA] ca,[TREES] t

Я ожидаю, что на выходе будет «Y», если дерево находится в охраняемой зоне, и «N», если это не так.

1 Ответ

1 голос
/ 11 апреля 2019

Вы соединяете все деревья со всеми заповедными зонами. Предположительно, ни одно дерево не находится внутри каждой области сохранения, поэтому конечный результат зависит от того, какое обновление SQL Server выберет для применения 1 (поскольку существует отдельное обновление Y или N применимо для каждой комбинации).

Вместо этого мы можем LEFT JOIN использовать тест пересечений:

UPDATE t
SET 
  IN_CONSERVATION_AREA = CASE
       WHEN ca.geom IS NULL
          THEN 'N'
       ELSE 'Y' END
FROM [TREES] t
  LEFT JOIN
    [CONSERVATION_AREA] ca
  ON t.[geom].STIntersects(ca.[geom]) = 1

Если дерево находится в нескольких охраняемых зонах, оно все равно будет пытаться обновить это дерево несколько раз, но по крайней мере все обновления будут одинаковыми (Y).

Обратите внимание, что в этой новой форме он может получить выгоду от Пространственных индексов , которые, как мы надеемся, у вас есть.

Как я уже сказал в комментариях, если у вас есть индексы, я бы предложил сначала проверить, выполняет ли эта же логика, когда извлекает , данные работают адекватно. Предпочитают , а не для хранения данных, которые могут быть вычислены - это просто оставляет возможность того, что они устарели (когда, скажем, кто-то добавляет новую область сохранения)


1 Некоторые системы баз данных будут жаловаться на ошибки по типу строки, подлежащей многократному обновлению! Но не SQL Server. Вместо этого задокументировано , чтобы оставить такие строки обновленными произвольно способом.

...