【问题标题】:Does this mySQL "spatial" query work in SQL Server 2008 as well?这个 mySQL “空间”查询是否也适用于 SQL Server 2008?
【发布时间】:2010-07-05 15:38:50
【问题描述】:

在我开始对我的网络应用程序进行相当大的改造以使用空间查询之前,我想知道这个 MySQL 查询是否适用于 SQL Server 2008:

SELECT id, ( 3959 * acos( cos( radians(37) ) * cos( radians( lat ) ) * 
        cos( radians( lng ) - radians(-122) ) + sin( radians(37) ) * 
        sin( radians( lat ) ) ) ) AS distance 
FROM markers HAVING distance < 25 
ORDER BY distance LIMIT 0 , 20;

或者在 SQL Server 2008 中有更好的方法吗?

我的数据库目前存储日本军事基地附近的经纬度企业。但是,我正在查询该表以查找包含指定基地 id 的企业。

Biz table
----------------------
PK BizId bigint (auto increment)
Name
Address
Lat
Long
**FK BaseId int (from the MilBase table)**

基于中心纬度/经度和给定半径(以千米为单位)的空间查询将更适合该应用,并会开辟一些新的可能性。

非常感谢任何帮助!

【问题讨论】:

    标签: sql sql-server-2008 stored-procedures geography


    【解决方案1】:

    看起来您正在选择两点之间的距离。在 SQL Server 2008 中,您可以使用 geography 数据类型的 STDistance 方法。这看起来像这样:

    SELECT   TOP 20
             geography::STGeomFromText('POINT(-122.0 37.0)', 4326).STDistance(p) 
    FROM     markers
    WHERE    geography::STGeomFromText('POINT(-122.0 37.0)', 4326).STDistance(p) < 25
    ORDER BY geography::STGeomFromText('POINT(-122.0 37.0)', 4326).STDistance(p);
    

    其中p 将是geography 类型的字段,而不是两个单独的decimal 字段。您可能还想在 p 字段上创建一个 spatial index 以获得更好的性能。

    要使用geography 数据类型,只需在CREATE TABLE 中将字段指定为geography

    CREATE TABLE markers ( 
        id     int IDENTITY (1,1),
        p      geography, 
        title  varchar(100) 
    );
    

    将值插入您的 markers 表现在将如下所示:

    INSERT INTO markers (id, p, title) 
    VALUES (
        1,
        geography::STGeomFromText('POINT(-122.0 37.0)', 4326),
        'My Marker'
    );    
    

    其中-122.0 是经度,37.0 是纬度。

    创建空间索引如下所示:

    CREATE SPATIAL INDEX  ix_sp_markers
                          ON markers(p)
                          USING GEOGRAPHY_GRID
                          WITH ( GRIDS = (HIGH, HIGH, HIGH, HIGH),
                                 CELLS_PER_OBJECT = 2,
                                 PAD_INDEX = ON);
    

    【讨论】:

    • 非常好...谢谢。即使我不使用地理类型,因为我使用的是 LINQ2SQL,但您的回答会有所帮助。非常感谢。
    【解决方案2】:

    如果您只对检索 25 英里范围内的点感兴趣,那么在距离计算中绝对不需要使用球面或大圆数学......仅使用标准的笛卡尔距离公式就足够了...... .

    Where  Square(Delta-X) + Square(Delta-Y) < 225  
    

    您所需要做的就是将纬度差异和经度差异转换为您使用的任何单位的里程(雕像英里海里等)

    如果您使用海里每度纬度 = 60 海里...
    并且每个经度度等于 60 * cos(Latitude) nm
    在这里,如果两个点之间的距离都在 25 英里以内,您甚至不必担心这一点与另一点之间的差异......

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多