2

我正在尝试创建一个递归 CTE 语句,该语句在数据点之间添加空白行,稍后将用于插值。我是 SQL 的初学者,这是我第一次使用 CTE,我很难找到正确的方法来做到这一点。

经过一些研究后,我尝试对下面提供的代码进行一些不同的细微修改,但还没有很好地理解我的问题。以下代码应通过每 4 小时从样本数据集中进行一次观察来模拟稀疏采样,第二部分应每 0.1 小时添加具有相应 x 值的行,稍后将填充从三次样条曲线派生的插值。

- 样本数据

create table #temperatures (hour integer, temperature double precision);
insert into #temperatures (hour, temperature) values
(0,18.5),
(1,16.9),
(2,15.3),
(3,14.1),
(4,13.8),
(5,14.7),
(6,14.7),
(7,13.5),
(8,12.2),
(9,11.4),
(10,10.9),
(11,10.5),
(12,12.3),
(13,16.4),
(14,22.3),
(15,27.2),
(16,31.1),
(17,34),
(18,35.6),
(19,33.1),
(20,25.1),
(21,21.3),
(22,22.3),
(23,20.3),
(24,18.4),
(25,16.8),
(26,15.6),
(27,15.4),
(28,14.7),
(29,14.1),
(30,14.2),
(31,14),
(32,13.9),
(33,13.9),
(34,13.6),
(35,13.1),
(36,15),
(37,18.2),
(38,21.8),
(39,24.1),
(40,25.7),
(41,29.9),
(42,28.9),
(43,31.7),
(44,29.4),
(45,30.7),
(46,29.9),
(47,27);

--1

WITH xy (x,y)
AS 
    (
  SELECT  TOP 12
    CAST(hour AS double precision) AS x
    ,temperature AS y 
    FROM #temperatures 
    WHERE cast(hour as integer) % 4 = 0
   )

Select x,y
INTO #xy
FROM xy

Select [x] As [x_input]
INTO #x_series
FROM #xy

--2

    with recursive
  , x_series(input_x) as (
    select
      min(x)
    from
      #xy
    union all
    select
      input_x + 0.1
    from
      x_series
    where
      input_x + 0.1 < (select max(x) from x)
  )
  , x_coordinate as (
  select
    input_x
    , max(x) over(order by input_x) as previous_x
  from
    x_series
  left join
    #xy on abs(x_series.input_x - xy.x) < 0.001
  )

第一个 CTE 按预期工作并产生 12 个列表(两天每 4 小时一个样本),但第二个产生语法错误。预期的输出将类似于

(4,13.8), (4.1,null/0), (4.2,null/0),....., (8,12.2)
4

3 回答 3

1

我认为您在这里不需要递归 CTE。我认为这样的解决方案将是一种更好的方法。相应地修改。

DECLARE @max_value FLOAT = 
    (SELECT MAX(hour) FROM  #temperatures) * 10

INSERT INTO #temperatures (hour, temperature)
SELECT X.N / 10, NULL
FROM (
    select CAST(ROW_NUMBER() over(order by t1.number) AS FLOAT) AS N
    from   master..spt_values t1 
           cross join master..spt_values t2
) X
WHERE X.N <= @max_value
    AND X.N NOT IN (SELECT hour FROM #temperatures)
于 2019-08-15T15:20:06.477 回答
1

我不认为你需要递归。

那这个呢:

SQL 演示

SELECT DISTINCT n = number *1.0 /10 , #xy.x, #xy.y
FROM master..[spt_values] step
LEFT JOIN #xy
  ON step.number*1.0 /10  = #xy.x
WHERE number BETWEEN 40 AND 480

这个480是根据你提到的两天计算的。

输出

在此处输入图像描述

你甚至不需要临时表

SELECT DISTINCT n = number *1.0 /10 , #temperatures.temperature
FROM master..[spt_values] step
LEFT JOIN #temperatures
  ON step.number *1.0 / 10  = #temperatures.hour
 AND  #temperatures.hour % 4 = 0
WHERE number BETWEEN 40 AND 480;
于 2019-08-15T15:20:25.547 回答
0

使用您在 --1 中生成的临时表#xy,以下将为您提供 ax 系列:

;with x_series(input_x)
as
(
    select min(x) AS input_x
    from #xy
    union all
    select input_x + 0.1
    from x_series
    where input_x + 0.1 < (select max(x) from #xy)
)
SELECT * FROM x_series;
于 2019-08-15T15:13:28.137 回答