4

我认为很容易解决的问题现在已经被窃听了很长一段时间。现在我需要你们的帮助。

在 Informix 中,我有一个像这样的“温度”表:

locId dtg 温度
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 温度
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 中建议的那样获取最新价格),但我无法让它工作。即使没有额外的“最近 20 分钟内的更新”也不会。

选择 t.*
从温度作为吨
 JOIN (select locId, max(dtg) from locId IN (100,200,400) group by locId) as l
    关于 l.locId=t.locId 和 l.dtg=t.dtg
其中 locId 在 (100,200,400)

这个查询给了我 SQL 错误,但我找不到错误。是否有我找不到的错误,或者这种方式在 Informix 中是不可能的。

还是有其他的方法可以走?所有帮助表示赞赏。

4

3 回答 3

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 语法。

于 2009-11-23T15:56:19.130 回答
1

You need to name the max(dtg) column in the subselect - your query just matches all rows by time not just the latest.

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)

You can add the where condition inside the sub select as well and also you could add a condition to get only the readings in the last 20 minutes.

edit: as per comment - I had typed the wrong join and other errors.


Some assistance - the references to t1 in the sub-query are wrong. You need an extra table reference (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)

This yields the result:

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

Unfortunately, this is not the required result, though it is getting closer. Part of the trouble is that you don't want t3.temp in the sub-select or its GROUP BY clause.

于 2009-11-23T15:52:40.357 回答
0

我选择创建一个单行表“RefDateTime”来保存参考时间(2009-02-25 10:10)。还有其他方法可以处理 - 特别是写 `DATETIME(2009-02-25 10:10) YEAR TO MINUTE。

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)的行。

于 2009-11-24T05:33:49.000 回答