我认为解决这个问题很简单,现在已经有了很长一段时间。现在我需要你们的帮助。
在Informix中,我有一个像这样的表“温度”:
locId dtg temp 100 2009-02-25 10:00 15 200 2009-02-25 10:00 20 300 2009-02-25 10:00 24 100 2009-02-25 09:45 13 300 2009-02-25 09:45 16 200 2009-02-25 09:45 18 400 2009-02-25 09:45 12 100 2009-02-25 09:30 11 300 2009-02-25 09:30 14 200 2009-02-25 09:30 15 400 2009-02-25 09:30 10
我正在尝试获取最近20分钟内更新值的每个locId的最新临时值。
所以我想从上表中得到的结果是(比如我在2009-02-25 10:10运行查询):
locId dtg temp 100 2009-02-25 10:00 15 200 2009-02-25 10:00 20 300 2009-02-25 10:00 24
使事情复杂化的另一件事是我希望能够在应该选择的locId上提供一个列表。我的意思是使用类似“...... locId IN(100,200,400)...”
的东西我曾尝试在子查询中使用连接(如SQL Query to get latest price中所述),但我无法使其工作。甚至没有额外的“在最后20分钟内更新”。
select t.* from temperatures as t JOIN (select locId, max(dtg) from temperatures where locId IN (100,200,400) group by locId) as l on l.locId=t.locId and l.dtg=t.dtg where locId in (100,200,400)
此查询给了我SQL错误,但我找不到错误。 是否有我无法找到的错误,或者这种方式在Informix中无法实现。
或者还有其他方法吗?所有帮助表示赞赏。
答案 0 :(得分:2)
您可以使用以下语法更正SQL错误:
SELECT t.*
FROM temperatures AS t
INNER JOIN (
SELECT locId, MAX(dtg) AS maxdtg
FROM temperatures
WHERE locId IN (100,200,400) GROUP BY locId
) AS l
ON l.locId = t.locId AND maxdtg = t.dtg
WHERE t.locId IN (100,200,400)
编辑:此外,还有一种正确且更具动态的方法:
SELECT t2.* FROM (
SELECT locId, MAX(dtg) AS maxdtg
FROM temperatures
GROUP BY locId
) t1
INNER JOIN (
SELECT locId, dtg, temp
FROM temperatures
) t2
ON t2.locId = t1.locId
AND t2.dtg = t1.maxdtg
WHERE t2.dtg > CURRENT YEAR TO MINUTE - 20 UNITS MINUTE
编辑:未来20分钟以上寻找帖子而不是20分钟......哎呀!
再次编辑:忘记这是针对Informix数据库...为where子句提供了MSSQL语法。
答案 1 :(得分:1)
您需要在子选择中命名max(dtg)列 - 您的查询只是按时间匹配所有行,而不仅仅是最新的。
select t1.locId, t1.temp, time
from temperatures t1
inner join ( select t1.locId, t1.temp, max(t1.dtg) as time
from temperatures group by t1.locId, t1.temp) as t2
on t1.locId = t2.locId
and t1.dtg = t2.time
where t1.locId in (100,200,400)
您也可以在子选择内添加where条件,也可以添加条件以仅获取最近20分钟内的读数。
编辑:根据评论 - 我输入了错误的连接和其他错误。
一些帮助 - 子查询中对t1的引用是错误的。您需要一个额外的表引用(t3):
select t1.locId, t1.temp, time
from temperatures t1
inner join (select t3.locId, t3.temp, max(t3.dtg) as time
from temperatures as t3 group by t3.locId, t3.temp) as t2
on t1.locId = t2.locId and t1.dtg = t2.time
where t1.locId in (100,200,400)
这产生了结果:
100 15 2009-02-25 10:00
200 20 2009-02-25 10:00
100 13 2009-02-25 09:45
200 18 2009-02-25 09:45
400 12 2009-02-25 09:45
100 11 2009-02-25 09:30
200 15 2009-02-25 09:30
400 10 2009-02-25 09:30
不幸的是,这不是必需的结果,尽管它越来越近了。部分麻烦在于您不希望在子选择或其GROUP BY子句中使用t3.temp。
答案 2 :(得分:0)
我选择创建一个单行表'RefDateTime'来保存参考时间(2009-02-25 10:10)。还有其他方法可以解决这个问题 - 特别是写“DATETIME(2009-02-25 10:10)年份”。
CREATE TABLE temperatures
(
locId INTEGER NOT NULL,
dtg DATETIME YEAR TO MINUTE NOT NULL,
temp INTEGER NOT NULL
);
INSERT INTO Temperatures VALUES(100, '2009-02-25 10:00', 15);
INSERT INTO Temperatures VALUES(200, '2009-02-25 10:00', 20);
INSERT INTO Temperatures VALUES(300, '2009-02-25 10:00', 24);
INSERT INTO Temperatures VALUES(100, '2009-02-25 09:45', 13);
INSERT INTO Temperatures VALUES(300, '2009-02-25 09:45', 16);
INSERT INTO Temperatures VALUES(200, '2009-02-25 09:45', 18);
INSERT INTO Temperatures VALUES(400, '2009-02-25 09:45', 12);
INSERT INTO Temperatures VALUES(100, '2009-02-25 09:30', 11);
INSERT INTO Temperatures VALUES(300, '2009-02-25 09:30', 14);
INSERT INTO Temperatures VALUES(200, '2009-02-25 09:30', 15);
INSERT INTO Temperatures VALUES(400, '2009-02-25 09:30', 10);
CREATE TABLE RefDateTime
(
reftime DATETIME YEAR TO MINUTE NOT NULL
);
INSERT INTO RefDateTime VALUES('2009-02-25 10:10');
SELECT t1.locID, t1.dtg, t1.temp
FROM temperatures AS t1 JOIN
(SELECT t2.locID, MAX(t2.dtg) AS latest
FROM temperatures AS t2
WHERE t2.dtg > (SELECT RefTime - 20 UNITS MINUTE FROM RefDateTime)
AND t2.locID IN (100, 200, 400)
GROUP BY t2.locID) AS t3 ON t1.locID = t3.locID AND t1.dtg = t3.latest
;
这给出了我认为正确的结果:
100 2009-02-25 10:00 15
200 2009-02-25 10:00 20
当省略't2.locID IN(100,200,400)'条件时,它还显示locID为300(温度为24)的行。