我试图从数据库中的两个表重建数据。第一个表(数据)包含时间值和代码。第二个表(信号)包含代码和描述。理想情况下,我希望最终得到下面显示的结果表,其中列按时间戳分组,行名称更改为描述符文本。
我设法在使用分组和多个转置的SQL查询后执行此操作,但这不能很好地扩展。
是否可以在SQL查询中执行所有这些功能?
数据表
CODE DESCRIPTOR
1000.ME Inlet Thermpcouple
1313.ME Air Flow
信号表
Timestamp Inlet Thermpcouple Air Flow
2016-05-11 13:56:47 26.900 9.1136
2016-05-11 13:56:51 26.900 9.1233
2016-05-11 13:56:56 26.900 9.1136
2016-05-11 13:57:00 27 9.1331
结果表
for(int i=0;i<imageList.size();i++){
File f= new File(imageList.get(i));
in = new BufferedInputStream(new FileInputStream(f));
reqEntity.addPart("file[" + i + "]",f.getName(), in);
}
}
答案 0 :(得分:1)
良好做法,感谢您发布问题!
这是一种做你需要的方法。该问题分为三个部分:首先,您需要连接两个表,以便拥有实际的描述符而不是代码。其次,您需要进行旋转,以便将入口热电偶和气流读数分成两列。第三,如果对于一个时间戳,您只有一个空气流量值,但没有入口热电偶的值,您希望IT值填充最新的读数(值)。
连接很简单,第三部分是使用LAG()
选项直接应用IGNORE NULLS
函数。 (注意 - 这个函数允许一个窗口子句;默认值是rows between unbounded preceding and current row
,这正是我们需要的,所以我没有使用这个参数 - 默认是完美的。)
唯一的问题是 - 除非您使用动态SQL - 必须知道您在SQL语句中使用的每个表中列的数量和名称。因此,使用#34; Inlet Thermocouple&#34;并不会有帮助。和&#34;气流&#34;作为表格中的描述符 - 它们在语句中仍然是硬编码。因此,您可以使用它,也可以这样编写查询,或者需要开发动态SQL代码。
下面是代码,包括您的测试数据,然后是查询的输出。
with data_table (ts, code, val) as (
select to_timestamp('2016-05-11 13:56:47', 'yyyy-mm-dd hh24:mi:ss'),
'1000.ME', 26.9 from dual union all
select to_timestamp('2016-05-11 13:56:47', 'yyyy-mm-dd hh24:mi:ss'),
'1313.ME', 9.1136 from dual union all
select to_timestamp('2016-05-11 13:56:51', 'yyyy-mm-dd hh24:mi:ss'),
'1313.ME', 9.1233 from dual union all
select to_timestamp('2016-05-11 13:56:56', 'yyyy-mm-dd hh24:mi:ss'),
'1313.ME', 9.1136 from dual union all
select to_timestamp('2016-05-11 13:57:00', 'yyyy-mm-dd hh24:mi:ss'),
'1000.ME', 27 from dual union all
select to_timestamp('2016-05-11 13:57:00', 'yyyy-mm-dd hh24:mi:ss'),
'1313.ME', 9.1331 from dual
),
signals_table (code, descriptor) as (
select '1000.ME', 'Inflow Thermocouple' from dual union all
select '1313.ME', 'Air Flow' from dual
),
j as (
select d.ts, s.descriptor, d.val from data_table d
inner join signals_table s on d.code = s.code
),
p as (
select * from j
pivot (min(val) for descriptor in ('Inflow Thermocouple' as it,
'Air Flow' as af))
)
select ts, last_value(it ignore nulls) over (order by ts) as "Inflow Thermocouple",
last_value(af ignore nulls) over (order by ts) as "Air Flow"
from p
order by ts;
注意 - 下面的输出显示实际的时间戳数据类型;我不确定你的&#34;时间戳&#34;列实际上是DATE数据类型或真正的时间戳,查询应该以任何一种方式工作。此外,使用Oracle关键字(例如&#34; timestamp&#34;或&#34; date&#34;)作为数据库中的表名或列名通常是一个非常糟糕的主意。我把它改成了ts。
TS Inflow Thermocouple Air Flow
--------------------------------------------- ------------------- ----------
11-MAY-16 01.56.47.000000000 26.9 9.1136
11-MAY-16 01.56.51.000000000 26.9 9.1233
11-MAY-16 01.56.56.000000000 26.9 9.1136
11-MAY-16 01.57.00.000000000 27 9.1331