[英]SQL to find the difference between two rows
我有一個 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
我已經嘗試了很多,但我找不到任何好的解決方案。 實際上,從 web 頁面詢問大約 700 個位置,所以我認為查詢需要相當有效。
真的很感激一些幫助!
//傑斯珀
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;
假設所有時間都是准確的
感謝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);
結果(比要求的列多,但您可以輕松修剪 select 列表):
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
請注意,此解決方案不依賴於 CURRENT(或 NOW); 它適用於最新記錄的數據。 SELECT 語句中唯一特定於 IDS 的部分是“ + 15 UNITS MINUTE
”; 這也可以在 Informix 中寫為 ' + INTERVAL(15) MINUTE TO MINUTE
TO MINUTE ',在標准 SQL 中寫為 ' + INTERVAL '15' MINUTE
'(如果 DBMS 支持 INTERVAL 類型)。 表中 DATETIME YEAR TO MINUTE 的使用是 Informix 特定的; 在這種情況下,不存儲您不感興趣的信息(例如秒數)很有用。
在偽 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
不確定您是否將其定義為“好的”解決方案,但如果每個位置有兩個數據點,它應該可以工作。
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 一樣,打敗我吧!
我不相信 Informix 具有 Oracle 之類的分析功能,但如果這樣做,這將是使用它們的絕佳場所。 以下是使用分析函數滯后和最大值的 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 分析的好資源: http://www.psoug.org/reference/analytic_functions.html
試試這樣的東西。 它可能不是超級高效,但與其他一些答案不同,它將返回每個 LocID 的差異
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 編寫了這篇文章,但嘗試盡可能地堅持標准 ANSI SQL 以便移植到 Informix。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.