2016-10-04 6 views
2

У меня есть таблица SQL из (x, y) значений.Интерполяция таблицы функций SQL

x  y 
0.0 0.0 
0.1 0.4 
0.5 1.0 
5.0 2.0 
6.0 4.0 
8.0 4.0 
10.0 5.0 

Столбец x проиндексирован. Я использую sqlite.

Моя конечная цель - получить y (x) для любого значения x. Я буду использовать линейную интерполяцию с использованием табличных значений. Как показано на рисунке ниже.

enter image description here

Есть ли способ для выполнения линейной интерполяции непосредственно с помощью запроса на выборку? Иначе получить значения интервалов, где принадлежит x, было бы достаточно.

Есть ли запрос, который даст мне последнюю меньшую и первую большую пару заданного x, чтобы я мог вычислить интерполированное значение y (x)?

Например, если x=2.0, чтобы получить:

0.5 1.0 
5.0 2.0 

В случае х вне таблицы, чтобы получить два первых/последнее значение для выполнения экстраполяции.

Например, если x=20.0 получить:

8.0 4.0 
10.0 5.0 
+0

Что вы хотите знать? Как получить значения y или как интерполировать? –

+0

@CL, оба или все, что возможно. Если интерполяция невозможна, достаточно получить две пары. – ztik

+0

@CL Я редактировал вопрос, чтобы сделать его более понятным. – ztik

ответ

2

Было бы трудно сделать это в простом SQLLite, без аналитических функций. В более сложных машинах SQL вы можете использовать аналитические функции LEG and LEAD для получения набора пар. Вы хотите достаточно легко. В SQLLite, хотя, я хотел бы создать два курсоры, как те:

Cursor C1:

SELECT 
    x,y 
FROM 
    table 
WHERE 
    x>=2 
ORDER BY 
    x asc 
; 

Cursor C2:

SELECT 
    x,y 
FROM 
    table 
WHERE 
    x<=2 
ORDER BY 
    x desc 
; 

И выполнять остальные операции на другом языке - выборка один раз из оба, или если один курсор не возвращает значение, дважды из другого. Кроме того, необходимо обработать некоторые дополнительные исключения - что, если ваш набор имеет менее двух значений. Или, если вы дали X в своем наборе - вам не требуется интерполяция вообще ... И так далее.

+0

Спасибо, я хотел бы иметь это в одном выборе. Это возможно? – ztik

+0

@ztik Почему? Какая проблема будет решена? –

+0

Я также не вижу смысла (или любого простого решения) для этого требования. В X индексируется, выборка из этих курсоров должна быть разумно быстрой. –

1

Я бы пошел с простой подстановкой.

Вы смотрите на два ближайшие вход так:

SELECT x, y 
FROM my_table 
ORDER BY Abs(:val - x) 
LIMIT 2 

Однако это приведет к полному сканированию таблицы.

+0

Nice мышления. Но он все еще нуждается в некоторой логике в своем приложении, чтобы проверить, должно ли это быть интерполяция или экстраполяция, и проверить, нужно ли вообще что-либо делать, и так далее. И полное сканирование таблицы не кажется хорошим с точки зрения предварительной работы. ;) Но это certailny простое и красивое решение! –

+0

Ну, сканирование таблицы само по себе не является проблемой. Это может быть проблемой, если таблица «большая» для ресурса. Теперь мы не знаем точной структуры таблицы, и если есть еще один выборочный столбец (например, graph_id), который приведет к полному сканированию или нет – Nemeros

+1

, я подумал об этом решении. Моя главная забота заключается в том, что он не всегда дает правильный интервал. Например, если «x = 0,6», то я получу 0,1 и 0,5 строки – ztik