从网上搜索到了已知一个点的经纬度(例如:经度113,纬度23),可以通过算法,从另一张表中找出距离此点最近的相关信息:SELECT TOP 1 B.*
    FROM table B
    ORDER BY SQUARE(B.经度-113)+SQUARE(纬度-23)现在的问题是,我有一张包含50多W条数据的表1,需要从另一张包含10W多条数据的表2中找出最近的那个点的某些信息,更新到表1中去,请教各位有没有效率高一些的方法。恳请赐教!

解决方案 »

  1.   

    空间搜索你用sql语句计算是不正确的,球面在平面上的投影并不是简单的两点间距离算法建议使用oracle spatial的geom字段或者sql2008的geometry字段对于海量数据,oracle spatial是可以使用空间索引提高效率
      

  2.   

    --SQL 2008使用空间数据SQL SERVER 2008支持两种空间数据类型,geometry和geography.其中geometry数据类型支持平面或平面球数据,geography可用于存储GPS经度和纬度坐标等椭球体数据。geometry和geography数据类型基于geometry层次结构。----point类型
    在SQL SERVER的空间数据中,Point用于定义一个点。例如:
    declare @g geometry
    set @g=geometry::STGeomFromText('POINT(3,4)',0)
    在本例中,字符串POINT(3,4)用于表示一个点,其中X坐标为3,Y坐标为4。
    使用下面的语句可以打印geometry变量@g的内容。
    select @g.Tostring()
    /*
    point(3,4)
    */
    geometry变量的STX属性表示其X坐标值,STY属性表示其Y坐标值。使用下面的语句可以打印@g的X和Y坐标值。
    select @g.STX
    select @g.STY也可以使用geometry::STPointFromText()方法根据指定格式的字符串生成POINT类型的geometry变量
    declare @g geometry;
    set @g=geometry::STGeomFromText('POINT(3,4)',0);
    select @g.STX;
    select @g.STY;----MultiPoint类型
    在SQL SERVER的空间数据中,Point用于定义多个点。
    declare @g geometry
    set @g=geometry::STGeomFromText('MultiPoint(3,4),(20 21),(1,2)',0)
    使用STGeometryN()方法可以获取MultiPoint类型数据中的一个点。例如@g.STGeometryN(1)
    表示@g中的第一个点.
    declare @g geometry
    set @g=geometry::STGeomFromText('MultiPoint(3,4),(20 21),(1,2)',0)
    declare @i int
    set @i=1
    print @g.tostring()
    whlie@i<4
    begin
      print @g.STGeometryN(@i).STX
      print @g.STGeometryN(@i).STY
      set @i=@i+1
    end
    /*
      MultiPoint(3,4),(20 21),(1,2)
      3
      4
      20
      21
      1
      2
    */----LineString类型
    在SQL SERVER的空间数据中,LineString是一维对象,用于表示一系列点和连接这些点的线段。
    下面的语句声明一个包含3个点的LineString类型的geometry对象。
    declare @g geometry
    set @g=geometry::STGeomFromText('LineString(3 4, 20 21,1 2)',4322)
    使用STNumPoints()方法可以返回构成实例的点数。
    declare @g geometry
    set @g=geometry::STGeomFromText('LineString(3 4, 20 21,1 2)',4322)
    select @g.STNumPoints()
    /*
    3
    */
    使用STPointN()方法可以获取LineString中指定的点。
    declare @g geometry
    set @g=geometry::STGeomFromText('LineString(3 4, 20 21,1 2)',4322)
    declare @i int
    set @i=1
    while @i<[email protected]()[email protected]()表示最后一个点
    begin
        select @g.STPointN(@i).ToString()
        set @i=@i+1
    end
    /*
     3 4
     20 21
     1  2
    */----MultiLineString类型
    在SQL SERVER的空间数据中,MultiLineString用于定义多个线段对象,即多个LineString.
    declare @g geometry
    set @g=geometry::STGeomFromText('MultiLineString((3 4,20 21),(21 22, 1 2))',13);----Polygon类型
    在SQL SERVER的空间数据中,Polygon是右一系列点和线段组成的二维图形(多边形).这些点和线段可以定义一个外部的边界环。也可以
    在外部边界环的内部定义零个或者多个内部环。
    declare @g geometry;
    set @g=geometry::STPolyFromText('Polygon((0 0,0 3,3 3,3 0,0 0),(1 1, 1 2, 2 1, 1 1))',10);
    Polygon对象的方法
    1.STExteriorRing方法
    使用STExteriorRing可以返回Polygon对象的外环。
    declare @g geometry;
    set @g=geometry::STPolyFromText('Polygon((0 0,0 3,3 3,3 0,0 0),(1 1, 1 2, 2 1, 1 1))',10);
    select @g.STExteriorRing().tostring();
    /*
    LINESTRING(0 0, 0 3, 3 3, 3 0, 0 0)
    */2.STNumterioring方法
    使用STNumterioring方法可以获取Polygon对象中包含的内环的数量。
    declare @g geometry;
    set @g=geometry::STPolyFromText('Polygon((0 0,0 3,3 3,3 0,0 0),(1 1, 1 2, 2 1, 1 1))',10);
    select @g.STExteriorRing().tostring();
    /*
    1
    */3.STInteriorRingN方法
    使用STInteriorRingN方法可以获取Polygon对象中包含的内环对象,即LineString对象。
    declare @g geometry;
    set @g=geometry::STPolyFromText('Polygon((0 0,0 3,3 3,3 0,0 0),(1 1, 1 2, 2 1, 1 1))',10);
    select @g.STExteriorRing().tostring();
    declare @i int
    set @i=1
    whlie @i<[email protected]()
    begin 
      select @g.STInteriorRingN(@i).tostring()
      set @i=@i+1
    end/*
    LINESTRING(1 1,1 2, 2 1,1 1)
    */----MultiPolygon类型
    在SQL SERVER的空间数据中,MultiPolygon用于定义多个多边形,即多个Polygon.
    declare @g geometry;
    set @g=geometry::Parse('MultiPolygon(((0 0,0 3, 3 3,3 0,0 0),(1 1,1 2,2 1,1 1)),((9 9,9 10,10 9,9 9))))');
    使用STGeometryN(1)表示@g中的第一个多边形。下面的代码可以输出MultiPolygon对象中所有多边形的字符串信息
    declare @g geometry;
    set @g=geometry::Parse('MultiPolygon(((0 0,0 3, 3 3,3 0,0 0),(1 1,1 2,2 1,1 1)),((9 9,9 10,10 9,9 9))))');
    declare @i int
    set @i=1
    print @g.tostring()
    while @i<3
    begin
       print @g.STGeometryN(@i).tostring();
       set @i=@i+1
    end
    /*
    MultiPolygon(((0 0,0 3, 3 3,3 0,0 0),(1 1,1 2,2 1,1 1)),((9 9,9 10,10 9,9 9))))
    Polygon((0 0,0 3, 3 3,3 0,0 0),(1 1,1 2,2 1,1 1))
    Polygon((9 9,9 10,10 9,9 9))
    */----GeometryCollection类型
    在SQL SERVER的空间数据中,GeometryCollection用于定义零个或者多个geometry或geography实例的集合。
    比如:
    declare @g geometry;
    set @g=geometry::STPolyFromText('GeometryCollection(point(3 21),Polygon((0 0,0 3,3 3,3 0,0 0)))',1);
    上面的例子中表示2个geometry实例,一个Point实例,一个Polygon实例。
    使用STNumGeometyies()方法可以获取集合中包含的几何图形数量。
    declare @g geometry;
    set @g=geometry::STPolyFromText('GeometryCollection(point(3 21),Polygon((0 0,0 3,3 3,3 0,0 0)))',1);
    select @g.STNumGeometyies()
    /*
    2
    */使用STGeometryN()方法可以获取GeometryCollection类型数据中指定的几何图形实例。例如STGeometryN(1)表示@g中的第1个几何图形实例。
    declare @g geometry;
    set @g=geometry::STPolyFromText('GeometryCollection(point(3 21),Polygon((0 0,0 3,3 3,3 0,0 0)))',1);
    declare @i int
    set @i=1
    print @g.Tostring()
    while @i<[email protected](@i).Tostring();
    set @i=@i+1
    end
    /*
    GeometryCollection(point(3 21),Polygon((0 0,0 3,3 3,3 0,0 0)))
    point(3 21)
    Polygon((0 0,0 3,3 3,3 0,0 0)))
    */
      

  3.   

    update a 
    set col = (SELECT TOP 1 col FROM table B where b.关键字 = a.关键字 ORDER BY SQUARE(B.经度-113)+SQUARE(纬度-23))
    from a
      

  4.   

    哇~~感谢您的资料,原来sql还有这么多的功能。
    但是对于我的情况,应该如何操作呢?
    目前我能想到的就是最简单的一行行去循环表1,并更新,但是这样做效率实在太低了。