@Mark がすでに指摘したように、にCROSS JOIN
は制限があります。ターゲット値が定義された値の範囲外になるとすぐに、レコードは返されません。
また、上記のソリューションは 1 つの結果のみに限定されます。私のプロジェクトでは、x 値のリスト全体を補間する必要があり、次の解決策を思いつきました。他の読者も興味を持つのではないでしょうか?
-- generate some grid data values in table #ddd:
CREATE TABLE #ddd (id int,x float,y float, PRIMARY KEY(id,x));
INSERT INTO #ddd VALUES (1,3,4),(1,4,5),(1,6,3),(1,10,2),
(2,1,4),(2,5,6),(2,6,5),(2,8,2);
SELECT * FROM #ddd;
-- target x-values in table #vals (results are to go into column yy):
CREATE TABLE #vals (xx float PRIMARY KEY,yy float null, itype int);
INSERT INTO #vals (xx) VALUES (1),(3),(4.3),(9),(12);
-- do the actual interpolation
WITH valstyp AS (
SELECT id ii,xx,
CASE WHEN min(x)<xx THEN CASE WHEN max(x)>xx THEN 1 ELSE 2 END ELSE 0 END flag,
min(x) xmi,max(x) xma
FROM #vals INNER JOIN #ddd ON id=1 GROUP BY xx,id
), ipol AS (
SELECT v.*,(b.x-xx)/(b.x-a.x) f,a.y ya,b.y yb
FROM valstyp v
INNER JOIN #ddd a ON a.id=ii AND a.x=(SELECT max(x) FROM #ddd WHERE id=ii
AND (flag=0 AND x=xmi OR flag=1 AND x<xx OR flag=2 AND x<xma))
INNER JOIN #ddd b ON b.id=ii AND b.x=(SELECT min(x) FROM #ddd WHERE id=ii
AND (flag=0 AND x>xmi OR flag=1 AND x>xx OR flag=2 AND x=xma))
)
UPDATE v SET yy=ROUND(f*ya+(1-f)*yb,8),itype=flag FROM #vals v INNER JOIN ipol i ON i.xx=v.xx;
-- list the interpolated results table:
SELECT * FROM #vals
上記のスクリプトを実行すると、テーブルに次のデータ グリッド ポイントが表示されます。#ddd
id x y
-- -- -
1 3 4
1 4 5
1 6 3
1 10 2
2 1 4
2 5 6
2 6 5
2 8 2
id=1
[[ テーブルには、2 つのアイデンティティ (と)のグリッド ポイントが含まれていますid=2
。私の例では、 CTE で1
使用して -groupのみを参照しました。これは、要件に合わせて変更できます。]]where id=1
valstyp
#vals
列に補間されたデータを含む結果テーブルyy
:
xx yy itype
--- ---- -----
1 2 0
3 4 0
4.3 4.7 1
9 2.25 1
12 1.5 2
最後の列itype
は、値の計算に使用された内挿/外挿のタイプを示します。
0: extrapolation to lower end
1: interpolation within given data range
2: extrapolation to higher end
この実際の例は、ここにあります。