我有两张桌子,简化如下。
CREATE TABLE value(
Timestamp DATETIME2,
Value float NOT NULL,
PRIMARY KEY(Timestamp)
);
CREATE TABLE location(
Timestamp DATETIME2,
Position GEOMETRY NOT NULL,
PRIMARY KEY(Timestamp)
);
执行简单的LEFT JOIN,例如:
SELECT V.Timestamp, V.Value, L.Position
FROM value V
LEFT JOIN location L ON V.Timestamp = L.Timestamp;
这会产生所有值,但在Timestamp
上没有完全匹配的情况下会出现NULL。
我的目标是为值表中的每个值获取插值位置。我需要以某种方式在我的查询中插入值,这就是我陷入困境的地方。
编辑:我发现我可以添加一个CASE语句来检查NULL
SELECT
V.Timestamp,
V.Value,
CASE WHEN L.Position IS NULL THEN
(<something clever here>)
ELSE
L.Position
END As Position
FROM value V
LEFT JOIN location L ON V.Timestamp = L.Timestamp;
答案 0 :(得分:3)
你看过Spatial Tools库了吗? link
它们具有插值功能,可以满足您的需求:
SqlGeometry InterpolateBetweenGeom(SqlGeometry start,SqlGeometry结束, 双倍距离)
我修改了我的第一个例子,现在计算两个最近点的中点,但我认为上面的库是一个更好的选择。要使用我的函数,你传入那些NULL位置的时间戳,函数将中点作为一个geom位置返回。
这可能对类似情况的人有用:
if object_id('dbo.fn_CalcMidPointByTime') is not null
drop function dbo.fn_CalcMidPointByTime;
go
create function [dbo].[fn_CalcMidPointByTime] (@baseTimestamp datetime2)
returns geometry
as
begin
declare @return geometry,
@fromPoint geometry,
@toPoint geometry;
declare @stage table (i tinyint, position geometry);
-- stage the high / low points
insert into @stage (i, position)
select row_number() over(order by d.[Timestamp] asc), position.ToString()
from ( select top(2) [Timestamp]
from dbo.Location
order by abs(datediff(ms, [Timestamp], @baseTimestamp)) asc
) as d([Timestamp])
join dbo.Location l on
d.[Timestamp] = l.[Timestamp];
select @fromPoint = position from @stage where i = 1;
select @toPoint = position from @stage where i = 2;
-- create linestring from the two points
declare @ls geometry = geometry::Parse(@fromPoint.STUnion(@toPoint).ToString()).STConvexHull().ToString();
-- draw a rectangle around the two points, and choose the center
select @return = @ls.STEnvelope().STCentroid();
return @return;
end
go
答案 1 :(得分:1)
我认为您应该更改查询以在每一行返回3组值:
这些应该是小于当前时间和位置的最大时间和位置,
当前时间和地点,
并且最小的时间和位置大于当前的时间和位置。
通过这种方式,每行都有足够的信息来进行数学运算......