Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL来查找两行之间的差异_Sql_Informix - Fatal编程技术网

SQL来查找两行之间的差异

SQL来查找两行之间的差异,sql,informix,Sql,Informix,我有一个Informix数据库,其中包含许多不同位置的测量温度值。所有位置每15分钟进行一次测量,然后将时间戳加载到同一表格中。表如下所示: locId dtg temp aaa 2009-02-25 10:00 15 bbb 2009-02-25 10:00 20 ccc 2009-02-25 10:00 24 aaa 2009-02-25 09:45 13 ccc 2009-02-25 09:45

我有一个Informix数据库,其中包含许多不同位置的测量温度值。所有位置每15分钟进行一次测量,然后将时间戳加载到同一表格中。表如下所示:

locId dtg temp aaa 2009-02-25 10:00 15 bbb 2009-02-25 10:00 20 ccc 2009-02-25 10:00 24 aaa 2009-02-25 09:45 13 ccc 2009-02-25 09:45 16 bbb 2009-02-25 09:45 18 ddd 2009-02-25 09:45 12 aaa 2009-02-25 09:30 11 ccc 2009-02-25 09:30 14 bbb 2009-02-25 09:30 15 ddd 2009-02-25 09:30 10 现在我想要一个查询,向我提供所有站点最后两次测量之间的温度变化。而且,只有那些有更新的度量的。例如,在上表中,不包括位置ddd。 结果是:

locId change aaa 2 bbb 2 ccc 8 我试了很多,但找不到好的解决办法。实际上,从一个网页上查询大约700个位置,所以我认为查询需要相当高效

非常感谢您的帮助!
//Jesper

在伪SQL中,您可以执行以下查询:

@now = Time Now

Select Oldest.LocId, Oldest.timestamp, Oldest.temp - Newest.temp as Change
(Select LocId, temp from Foo where timestamp < @now - 15 mins AND timestamp >= @now - 30 mins) Oldest
   left join
(Select LocId, temp from Foo where timestamp >= TimeNow - 15 mins) Newest
   on Oldest.LocId = Newest.LocId
不确定您是否将其定义为“好”解决方案,但如果每个位置都有两个数据点,它应该可以工作

set now = select max(dtg) from table;
set then = select max(dtg) from table where dtg < now;

select locID, old.temp-new.temp from 
      table as old join
      table as new 
      on old.locId = new.locID
where
      old.dtg = then and
      new.dtg = now;
假设所有时间都是精确的

declare @dt_latest datetime, @dt_prev datetime  

select @dt_latest = max(dtg) from Measures
select @dt_prev = max(dtg) from Measures where dtg < @dt_latest  

select Latest.Locid, Latest.temp - Prev.temp
from Measures as "Latest"
inner join Measures as "Prev" on Latest.Locid = Prev.Locid
where Latest.dtg = @dt_latest
and Prev.dtg = @dt_prev

编辑:基本上和BCS一样,比我快

试试这样的东西。它可能不是超高效的,但与其他一些答案不同,它将返回每个LocID的dif

SELECT DISTINCT LocID,
            (SELECT max(t3.temp)-min(t3.temp) from 
                   (SELECT TOP 2 T2.temp 
                    From Table2 T2 
                    Where (t2.Locid=t1.locid) 
                    order by DTG DESC) as t3
             ) as Diff
     FROM Table1 T1

警告:我使用tSQL编写了这篇文章,但为了能够移植到Informix,我尽量坚持使用标准的ANSI SQL。

我不相信Informix有像Oracle这样的分析功能,但如果它有这样的功能,这将是一个很好的使用它们的地方。下面是一个使用分析函数lag和max的Oracle示例

安装脚本:

drop table temps;
create table temps (
locId varchar2(3),
dtg date,
temp number(3)
);

insert into temps values ('aaa', to_date('2009-02-25 10:00','yyyy-mm-dd hh:mi'), 15);
insert into temps values ('bbb', to_date('2009-02-25 10:00','yyyy-mm-dd hh:mi'), 20);
insert into temps values ('ccc', to_date('2009-02-25 10:00','yyyy-mm-dd hh:mi'), 24);
insert into temps values ('aaa', to_date('2009-02-25 09:45','yyyy-mm-dd hh:mi'), 13);
insert into temps values ('ccc', to_date('2009-02-25 09:45','yyyy-mm-dd hh:mi'), 16);
insert into temps values ('bbb', to_date('2009-02-25 09:45','yyyy-mm-dd hh:mi'), 18);
insert into temps values ('ddd', to_date('2009-02-25 09:45','yyyy-mm-dd hh:mi'), 12);
insert into temps values ('aaa', to_date('2009-02-25 09:30','yyyy-mm-dd hh:mi'), 11);
insert into temps values ('ccc', to_date('2009-02-25 09:30','yyyy-mm-dd hh:mi'), 14);
insert into temps values ('bbb', to_date('2009-02-25 09:30','yyyy-mm-dd hh:mi'), 15);
insert into temps values ('ddd', to_date('2009-02-25 09:30','yyyy-mm-dd hh:mi'), 10);
commit;
使用分析函数的Oracle特定查询:

select locId, change
  from (
select t.locId,
       t.dtg,
       t.temp,
       -- difference between this records temperature and the record before it 
       t.temp - lag(t.temp) over (partition by t.locId order by t.dtg) change,
       -- max date for this location
       max(t.dtg) over (partition by t.locId) maxDtg,
       max(t.dtg) over (partition by 1) overallMaxDtg
  from temps t
 order by t.locId, t.dtg
 ) where maxDtg = dtg -- only most recent measurement
     and overallMaxDtg = maxDtg -- only stations with an 'updated measurement'
     ;
结果:

LOCID CHANGE

aaa   2
bbb   2
ccc   8

Oracle分析方面的优秀资源:

感谢uglysmurf以SQL格式提供数据

使用IDS IBM Informix Dynamic Server 11.50版,以下查询可以工作

CREATE TEMP TABLE temps
(
    locId   CHAR(3),
    dtg     DATETIME YEAR TO MINUTE,
    temp    SMALLINT
);
INSERT INTO temps VALUES ('aaa', '2009-02-25 10:00', 15);
INSERT INTO temps VALUES ('bbb', '2009-02-25 10:00', 20);
INSERT INTO temps VALUES ('ccc', '2009-02-25 10:00', 24);
INSERT INTO temps VALUES ('aaa', '2009-02-25 09:45', 13);
INSERT INTO temps VALUES ('ccc', '2009-02-25 09:45', 16);
INSERT INTO temps VALUES ('bbb', '2009-02-25 09:45', 18);
INSERT INTO temps VALUES ('ddd', '2009-02-25 09:45', 12);
INSERT INTO temps VALUES ('aaa', '2009-02-25 09:30', 11);
INSERT INTO temps VALUES ('ccc', '2009-02-25 09:30', 14);
INSERT INTO temps VALUES ('bbb', '2009-02-25 09:30', 15);
INSERT INTO temps VALUES ('ddd', '2009-02-25 09:30', 10);

SELECT latest.locID, latest.temp, prior.temp,
       latest.temp - prior.temp as delta_temp,
       latest.dtg, prior.dtg
    FROM temps latest, temps prior
    WHERE latest.locId = prior.locId
      AND latest.dtg = prior.dtg + 15 UNITS MINUTE
      AND latest.dtg = (SELECT MAX(dtg) FROM temps);
结果列数超过请求的列数,但您可以轻松修剪选择列表:

aaa 15 13 2 2009-02-25 10:00 2009-02-25 09:45
ccc 24 16 8 2009-02-25 10:00 2009-02-25 09:45
bbb 20 18 2 2009-02-25 10:00 2009-02-25 09:45

请注意,此解决方案不依赖于当前或现在;它对最新记录的数据起作用。SELECT语句中唯一特定于IDS的部分是“+15单位分钟”;如果DBMS支持区间类型,则在Informix中也可以写成“+INTERVAL15分钟到分钟”,在标准SQL中可以写成“+INTERVAL”15分钟。在表中使用DATETIME YEAR TO MINUTE是特定于Informix的;在这样的环境中,最好不要存储您不感兴趣的信息,例如秒。

所有时间都是精确的。我认为此代码假定所有位置的最近两次读数将彼此在同一时间。似乎不太可能。还可能需要编辑软件,这取决于设置方式。这很容易发生在拉力模型中。我只是想确保OP明白它只能在这种情况下工作。这段代码使用了Informix不支持的符号。为什么不包括ddd?它在9:30时有一个条目,温度为10,在9:45时有另一个条目,温度为12。只有在10:00和9:45时有数据的站点才包括在内,没有分析,我更喜欢这种纯SQL的解决方案,与BCS不同,BCS使用三个独立的查询和临时变量……完全没有必要。Jonathan Leffler的一个技巧是:使用更具描述性的表别名。新的和旧的比a和b提供更多的信息。为了可读性,我还重新排列了一些谓词,以便old.dtg=new.dtg-15…,new.dtg=SELECT MAX。。。。这样就很清楚什么是新老的dtg了。@uglysmurf:Fair comment;我将据此进行编辑。对于试用工作,我使用短别名-我只是没有转换为“非试用”模式。