Как я могу эффективно выбрать ближайшее значение, меньшее и большее, чем данное значение?

У меня есть две таблицы, одна для значений, другая для местоположения, и я пытаюсь интерполировать местоположение. Таблицы были упрощены до следующего:

CREATE TABLE value(
    Timestamp DATETIME2,
    Value float NOT NULL,
    PRIMARY KEY(Timestamp)
);

CREATE TABLE location(
    Timestamp DATETIME2,
    Position INT NOT NULL,
    PRIMARY KEY(Timestamp)
); 

INSERT INTO value VALUES 
    ('2011/12/1 16:55:01', 1),
    ('2011/12/1 16:55:02', 5),
    ('2011/12/1 16:55:05', 10),
    ('2011/12/1 16:55:08', 6);

INSERT INTO location VALUES 
    ('2011/12/1 16:55:00', 0),
    ('2011/12/1 16:55:05', 10),
    ('2011/12/1 16:55:10', 5)

Ожидаемые результаты будут

TimeStamp, Value, LowerTime, LowerLocation, UpperTime, UpperLocation
2011-12-01 16:55:01,  1, 2011-12-01 16:55:00,  0, 2011-12-01 16:55:05, 10
2011-12-01 16:55:02,  5, 2011-12-01 16:55:00,  0, 2011-12-01 16:55:05, 10
2011-12-01 16:55:05, 10, 2011-12-01 16:55:05, 10, 2011-12-01 16:55:05, 10
2011-12-01 16:55:08,  6, 2011-12-01 16:55:05, 10, 2011-12-01 16:55:10,  5

(имейте в виду, что это упрощенные образцы данных, чтобы получить представление о запросе, который я пытаюсь выполнить.)

Чтобы выполнить интерполяцию, мне нужно вычислить время и местоположения до и после заданного времени значений. В настоящее время я делаю это с помощью запроса, который выглядит примерно так:

SELECT 
    V.Timestamp, 
    V.Value, 
    (SELECT MAX(Timestamp) FROM dbo.location WHERE Timestamp <= V.Timestamp) as LowerTime,
    (SELECT TOP 1 Position FROM dbo.location WHERE Timestamp <= V.Timestamp ORDER BY timestamp DESC) as LowerLocation,
    (SELECT MIN(Timestamp) FROM dbo.location WHERE Timestamp >= V.Timestamp) as UpperTime,
    (SELECT TOP 1 Position FROM dbo.location WHERE Timestamp >= V.Timestamp ORDER BY timestamp ASC) as UpperLocation
 FROM 
    dbo.value V 

Теперь это работает, но, очевидно, выполняется много работы. Я думаю, что должно быть упрощение запроса, которое Мне не хватает, но я играл с этим все утро и не придумал ничего конкретного. Надеюсь, у кого-то есть идея получше.

В настоящее время я изучаю, есть ли способ выяснить LowerTime и UpperTime и используйте их для определения местоположений. Что-то вроде:

SELECT 
    V.Timestamp, 
    V.Value, 
    (SELECT MAX(Timestamp) FROM dbo.location WHERE Timestamp <= V.Timestamp) as LowerTime,
    (SELECT Position FROM dbo.location WHERE Timestamp = LowerTime) as LowerLocation,
    (SELECT MIN(Timestamp) FROM dbo.location WHERE Timestamp >= V.Timestamp) as UpperTime,
    (SELECT Position FROM dbo.location WHERE Timestamp = UpperTime) as UpperLocation
 FROM 
    dbo.value V 

, но это не работает.

РЕДАКТИРОВАТЬ1: Обновленный запрос, как предложено. Однако никаких видимых изменений во времени выполнения.

РЕДАКТИРОВАТЬ2: Добавлены мои мысли о подходе, который я сейчас пытаюсь.

7
задан brianestey 20 January 2012 в 10:03
поделиться