从两个表重建数据并重命名表数据中的行

时间:2016-05-13 13:26:45

标签: sql oracle pivot transpose

我试图从数据库中的两个表重建数据。第一个表(数据)包含时间值和代码。第二个表(信号)包含代码和描述。理想情况下,我希望最终得到下面显示的结果表,其中列按时间戳分组,行名称更改为描述符文本。

我设法在使用分组和多个转置的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);    

                                }
                            }

1 个答案:

答案 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