4

私が解決するのは簡単なことだと思っていたことが、今ではかなり長い間バグになっています。今、私は皆さんからの助けが必要です。

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

物事を複雑にするもう 1 つのことは、選択する必要がある locId のリストを提供できるようにしたいということです。「...locId IN (100,200,400)...」のようなものを使用することを意味します

サブクエリで結合を使用しようとしました (最新の価格を取得するための SQL クエリで提案されているように) が、機能しません。余分な「過去20分以内の更新」がなくても。

t.* を選択
t としての温度から
 JOIN (locId IN (100,200,400) を locId でグループ化した温度から locId, max(dtg) を選択) as l
    l.locId=t.locId および l.dtg=t.dtg で
(100,200,400) の locId

このクエリでは 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)

編集:また、これを実行するための1つの適切でより動的な方法:

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

副選択で 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 を使用したくないことです。

于 2009-11-23T15:52:40.357 に答える
0

参照時刻 (2009-02-25 10:10) を保持するために、1 行のテーブル 'RefDateTime' を作成することにしました。これを処理する方法は他にもあります - 特に `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 に答える