如何在不使用游标的情况下为Sql Server 2008中的每个代码执行此操作?

时间:2010-09-17 04:55:42

标签: sql-server-2008 cursor set spatial

如果可能,我希望在不使用CURSOR的情况下在Sql中执行以下pseduo代码。

for each zipcode
{
    -- What city is this zipcode in? A zipcode can be in multiple cities, 
    -- but one city area is always way greater that the others.
    -- Eg. 90210 is 96% in the city of Beverly Hills. 
    -- The remaining 4% is that it s in some other fringe cties .. 
    --but only just (some mismatch mapping errors).

    ** grab the city largest shape area which this zip is a part of **
}

现在,我有一些SQL来帮助我们。

-- All zipcodes and each boundary/shapefile.
SELECT ZipCodeId, Boundary FROM ZipCodes -- Boundary is a GEOGRAPHY field type.

To determine if a zipcode boundary is in a city....
SELECT CityId, CityName, 
    City.Boundary.Intersection(@someZipCodeBoundary).STArea() AS Area
FROM Cities
WHERE City.Boundary.Intersects(@someZipCodeBoundary) = 1

并获得交叉区域(因为我们想要最高的交叉区域...即。TOP(1) ORDER BY Area DESCDISTINCT with an ORDER BY .. sorta事物......我们使用{{ 1}} sql方法。

注意:IntersectionIntersects是两种不同的 Sql方法。

那么..谁能帮助我?我吮吸所有这些Intersection的东西:(

4 个答案:

答案 0 :(得分:0)

Max是否适用于此?

答案 1 :(得分:0)

我必须说我不知道​​Intersection / Intersects是什么或者他们做了什么,我必须澄清我不理解Boundary.Intersection(@someZipCodeBoundary).下面的语法

假设您的此查询返回与指定的zipcodeBoundary相交的所有城市,而Area是其交叉区域

SELECT 
    CityId, 
    CityName, 
    City.Boundary.Intersection(@someZipCodeBoundary).STArea() AS Area 
FROM 
    Cities 
WHERE 
    City.Boundary.Intersects(@someZipCodeBoundary) = 1 

根据我的理解,drachenstern上面提出的建议是关于使用MAX

SELECT 
    CityId, 
    MAX(City.Boundary.Intersection(@someZipCodeBoundary).STArea()) AS Area
FROM 
    Cities 
WHERE 
    City.Boundary.Intersects(@someZipCodeBoundary) = 1 
GROUP BY CityId

这应该为您提供具有MAXIMUM交叉区域的CITYID。

答案 2 :(得分:0)

好的 - 得到了;)诀窍是使用PARTITION BY。 @In Sane在我意识到我做过类似的事情时给了我这个想法,之前:)

所以......我们走了..

SELECT 
    a.CityId, a.Name, b.ZipCodeId, b.Code, a.Boundary.STIntersection(b.Boundary).STArea() AS Area, 
    RANK() OVER (PARTITION BY b.ZipCodeId ORDER BY a.Boundary.STIntersection(b.Boundary).STArea() DESC) AS Area_Rank
FROM 
    Cities a
    INNER JOIN ZipCodes b on a.Boundary.STIntersects(b.Boundary) = 1
    where b.Code = 12010 OR b.Code = 90210


CityId      Name                                                                                                 ZipCodeId   Code                 Area                   Area_Rank
----------- ---------------------------------------------------------------------------------------------------- ----------- -------------------- ---------------------- --------------------
2166        Los Angeles                                                                                          9331        90210                13235413.8430175       1
1686        Beverly Hills                                                                                        9331        90210                10413397.1372613       2
2635        West Hollywood                                                                                       9331        90210                0                      3
14570       Amsterdam                                                                                            29779       12010                15369521.9602067       1
14921       Hagaman                                                                                              29779       12010                1394562.70390667       2
14856       Fort Johnson                                                                                         29779       12010                211058.884834718       3
14651       Broadalbin                                                                                           29779       12010                0                      4

(7 row(s) affected)

所以在这个过滤的例子中(由ZipCode 12010或90210过滤),我们可以看到这个邮政编码存在于4个不同的城市/城镇。每个邮政编码可以有1到多个结果,然后按区域值排序..但这里的关键是PARTITION关键字..它由ZipCode组或分区进行排序。非常时髦:)请注意邮政编码90210如何拥有自己的排名结果?与12010相同?

接下来,我们制作一个子查询,然后抓住所有Rank == 1:)

SELECT CityId, Name, ZipCodeId, Code, Area_Rank
FROM (
SELECT 
    a.CityId, a.Name, b.ZipCodeId, b.Code, a.Boundary.STIntersection(b.Boundary).STArea() AS Area, 
    RANK() OVER (PARTITION BY b.ZipCodeId ORDER BY a.Boundary.STIntersection(b.Boundary).STArea() DESC) AS Area_Rank
FROM 
    Cities a
    INNER JOIN ZipCodes b on a.Boundary.STIntersects(b.Boundary) = 1
    where b.Code = 12010 OR b.Code = 90210
) subQuery
WHERE Area_Rank = 1


CityId      Name                                                                                                 ZipCodeId   Code                 Area_Rank
----------- ---------------------------------------------------------------------------------------------------- ----------- -------------------- --------------------
14570       Amsterdam                                                                                            29779       12010                1
2166        Los Angeles                                                                                          9331        90210                1

(2 row(s) affected)

像糖果一样甜蜜:)。

旁注:这也告诉我,我的洛杉矶城市shapefile /边界已损坏,因为它与邮政编码90210相交太多了(我在视觉上确认了这一点:P)

alt text

答案 3 :(得分:-1)

尝试另一种方法。获取人口普查统计数据并筛选出按相同邮政编码分组的最大人口数量的城市。

例如,像Gazetteer thing一样。