这个 mySQL “空间”查询是不是也适用于 SQL Server 2008?

Posted

技术标签:

【中文标题】这个 mySQL “空间”查询是不是也适用于 SQL Server 2008?【英文标题】: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)**

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

非常感谢任何帮助!

【问题讨论】:

【参考方案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 英里以内,您甚至不必担心这一点与另一点之间的差异......

【讨论】:

以上是关于这个 mySQL “空间”查询是不是也适用于 SQL Server 2008?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 mysql 中的这个查询适用于该表,但不适用于该表的视图?

MySQL 索引

为啥这种“嵌套连接”适用于 PDO 而不适用于 MySql cli?

mysql最好的优化技巧

Connection.setAutoCommit(true) 是不是适用于 SQL 存储过程和函数?

MySQL - WHERE 子句中的 NOT IN 查询具有相同的结构,适用于第一个表但不适用于第二个表