距离公式中的tsql大小写语法

距离公式中的tsql大小写语法,tsql,Tsql,acos函数在-1然后1的时间间隔内工作 当cos(弧度(@latitude))*cos(弧度(thing_geology.ga_thing))*cos(弧度(thing_geology.go_thing)-弧度(经度))+sin(弧度(@latitude))*sin(弧度(thing_geology.ga_thing))1.0 设置@Result=1.0 否则,如果@Result

acos函数在-1然后1的时间间隔内工作 当cos(弧度(@latitude))*cos(弧度(thing_geology.ga_thing))*cos(弧度(thing_geology.go_thing)-弧度(经度))+sin(弧度(@latitude))*sin(弧度(thing_geology.ga_thing))<-1然后-1 else cos(弧度(@纬度))*cos(弧度(thing_geology.ga_thing))*cos(弧度(thing_geology.go_thing)-弧度(经度))+sin(弧度(@纬度))*sin(弧度(thing_geology.ga_thing)) 结束 ) ) < 1.5 但是,听起来不是很好(这会导致计算距离3x,对吗?)

我有其他的想法,比如子查询或outerapply,但是由于Entry查询非常复杂,并且相同的字段用于其他目的,所以我尝试在不改变整个查询的情况下解决它

ps:我试着使用point.distance函数,但是它不能很好地处理空值,所以我选择保持这种方式


有什么想法吗?

我建议将传递到
acos
的所有内容都更改为用户定义的标量值函数。在该函数中,可以考虑大于1.0或小于-1.0的值

通过这样做,您不必执行任何超出必要范围的数学计算

我认为你的函数应该是这样的:

    where
        (
            6371 *
            acos
            (
                case
                    when cos(radians(@latitude)) * cos(radians(thing_geolocation.ga_thing)) * cos(radians(thing_geolocation.go_thing) - radians(@longitude)) + sin(radians(@latitude)) * sin(radians(thing_geolocation.ga_thing)) > 1 then 1
                    when cos(radians(@latitude)) * cos(radians(thing_geolocation.ga_thing)) * cos(radians(thing_geolocation.go_thing) - radians(@longitude)) + sin(radians(@latitude)) * sin(radians(thing_geolocation.ga_thing)) < -1 then -1
                    else cos(radians(@latitude)) * cos(radians(thing_geolocation.ga_thing)) * cos(radians(thing_geolocation.go_thing) - radians(@longitude)) + sin(radians(@latitude)) * sin(radians(thing_geolocation.ga_thing))
                end
            )
        ) < 1.5 
CREATE FUNCTION [dbo].[udf_GetACOSInputValueByLatLong]
(
    @LatStart DECIMAL(10,6),
    @LongStart DECIMAL(10,6),
    @LatEnd DECIMAL(10,6),
    @LongEnd DECIMAL(10,6)
)
RETURNS DECIMAL(10,6) AS 
BEGIN

DECLARE @Result DECIMAL(10, 6)
SET @Result = ( 
    cos( radians( @LatStart ) ) * 
    cos( radians( @LatEnd ) ) * 
    cos( radians( @LongEnd ) - radians(@LongStart) ) + sin( radians(@LatStart) ) * 
    sin( radians( @LatEnd ) ) 
)

IF @Result > 1.0
    SET @Result = 1.0
ELSE IF @Result < -1.0
    SET @Result = -1.0

RETURN (@Result)

END
创建函数[dbo]。[udf_GetACOSInputValueByLatLong]
(
@LatStart十进制(10,6),
@LongStart十进制(10,6),
@最晚十进制数(10,6),
@长端十进制(10,6)
)
将十进制(10,6)返回为
开始
声明@Result DECIMAL(10,6)
设置@Result=(
cos(弧度(@LatStart))*
cos(弧度(@LatEnd))*
cos(弧度(@LongEnd)-弧度(@LongStart))+sin(弧度(@LatStart))*
sin(弧度(@LatEnd))
)
如果@Result>1.0
设置@Result=1.0
否则,如果@Result<-1.0
设置@Result=-1.0
返回(@Result)
结束
然后可以像下面这样使用:

where
    (
        6371 * acos (YourDatabase.dbo.udf_GetACOSInputValueByLatLong(
            @latitude, 
            @longitude, 
            thing_geolocation.ga_thing, 
            thing_geolocation.go_thing))
    ) < 1.5
在哪里
(
6371*acos(YourDatabase.dbo.udf_GetACOSInputValueByLatLong(
@纬度,
@经度,
地理位置,地理位置,地理位置,
东西(地理位置,去东西)
) < 1.5

如果要走到这一步,为什么不创建一个CalculateInstance函数呢。您只需在函数中移动ACO和常量。此外,弧度函数比使用常量慢。
where
    (
        6371 * acos (YourDatabase.dbo.udf_GetACOSInputValueByLatLong(
            @latitude, 
            @longitude, 
            thing_geolocation.ga_thing, 
            thing_geolocation.go_thing))
    ) < 1.5