Сохранять среднее значение всех точек в пределах многоугольника в новом поле - PullRequest
1 голос
/ 19 июня 2019

У меня есть слой с полигонами и слой с адресными точками.

Следующий запрос завершен:

SELECT zones.OBJECTID, Avg(address.WalkTime)
FROM address
JOIN zones
ON zones.Shape.STContains(address.Shape) = 1
GROUP BY mb.OBJECTID

╔══════════╦════════════════╗
║ OBJECTID ║ No column Name ║
╠══════════╬════════════════╣
║       31 ║ 8.1            ║
║       41 ║ 5.3            ║
║       55 ║ 12.5           ║
║       78 ║ 10.4           ║
║       94 ║ 9.7            ║
╚══════════╩════════════════╝

У меня есть новый пустой числовой столбец в зонах под названием Avg_WalkTime

Как мне адаптироватьсязапрос на вставку среднего значения в этот столбец?

Попытка:

UPDATE 
    zones 
SET  
    zones.Avg_WalkTime = (
    SELECT Avg(address.WalkTime)
        FROM address
    WHERE zones.Shape.STContains(address.Shape) = 1

Однако это не удается с неправильным синтаксисом?

1 Ответ

1 голос
/ 19 июня 2019

Вы не можете GROUP BY и обновлять одновременно, потому что строки были сгруппированы, а ссылка на исходную исходную строку «потеряна».

Вы можете использовать CTE или подзапрос для вычисления среднего значения, а затем присоединиться к исходной таблице через набор столбцов, который правильно идентифицирует строку. Я предполагаю, что это OBJECTID для этого случая.

;WITH Averages AS
(
    SELECT 
        zones.OBJECTID, 
        Average = Avg(address.WalkTime)
    FROM 
        address
        JOIN zones ON zones.Shape.STContains(address.Shape) = 1
    GROUP BY 
        zones.OBJECTID
)
UPDATE Z set
    Avg_WalkTime = A.Average
FROM
    zones AS Z
    INNER JOIN Averages AS A ON Z.OBJECTID = A.OBJECTID

Другое решение, использующее коррелированный подзапрос. Этот обновит все zones, даже если на address нет подходящей строки (в среднем будет установлено значение NULL). Предыдущая будет обновлять только те зоны, которые имеют как минимум 1 адрес (INNER JOIN).

UPDATE Z SET
    Avg_WalkTime = (SELECT Avg(A.WalkTime) FROM address AS A WHERE Z.Shape.STContains(A.Shape) = 1)
FROM
    zones AS Z
...