有没有更有效的方法来返回SQL中最大空间交集的记录?

时间:2019-03-15 14:45:57

标签: sql sql-server geometry

我在SQL中有两个表。第一个是项目多边形。第二个是我要基于最大空间交集应用于多边形的任何边界。

例如,如果项目1重叠2个州,我想返回项目1所在区域最多的州名称。

我已经完成了下面的查询。 PrjID是项目表,STATE是状态表。我想根据每个PrjID记录和STATE记录之间的最大交集返回statename。

SELECT *
FROM
(SELECT a.PROJECT_DELIVERY_ID, b.statename, a.Shape.STIntersection(b.Shape).STArea() AS Area
    FROM PrjID a
        INNER JOIN STATE b
            ON a.Shape.STIntersects(b.Shape) = 1) as c
INNER JOIN
(SELECT a.PROJECT_DELIVERY_ID, MAX(a.Shape.STIntersection(b.Shape).STArea()) AS Area
    FROM PrjID a
        INNER JOIN STATE b
            ON a.Shape.STIntersects(b.Shape) = 1
    GROUP BY a.PROJECT_DELIVERY_ID) as d
ON c.PROJECT_DELIVERY_ID = d.PROJECT_DELIVERY_ID
    AND c.Area = d.Area

我感觉自己在两次运行相同的查询并将其加入。有更有效的方法吗?

谢谢

2 个答案:

答案 0 :(得分:2)

如果我正确的话,您想获得最大面积的行。您可以使用ROW_NUMBER()

SELECT * FROM (
    SELECT a.PROJECT_DELIVERY_ID, b.statename, a.Shape.STIntersection(b.Shape).STArea() AS Area, 
        ROW_NUMBER() OVER(PARTITION BY a.PROJECT_DELIVERY_ID ORDER BY a.Shape.STIntersection(b.Shape).STArea() DESC) RN
        FROM PrjID a
            INNER JOIN STATE b
                ON a.Shape.STIntersects(b.Shape) = 1 ) AS T
WHERE RN = 1

答案 1 :(得分:1)

由于可以从第一个“表表达式”构建第二个“表表达式”,因此可以使用CTE(通用表表达式),如下所示:

with
c as (
  SELECT
    a.PROJECT_DELIVERY_ID, 
    b.statename,
    a.Shape.STIntersection(b.Shape).STArea() AS Area
  FROM PrjID a
  INNER JOIN STATE b ON a.Shape.STIntersects(b.Shape) = 1
),
d as (
  select PROJECT_DELIVERY_ID, max(Area) AS Area
  from c
  group by PROJECT_DELIVERY_ID
)
select * 
from c
join d on c.PROJECT_DELIVERY_ID = d.PROJECT_DELIVERY_ID
    AND c.Area = d.Area

此处d是根据c计算的。无需再次扫描表PrjIDSTATE