簡體   English   中英

SQL查詢以獲取每個位置的“最新”值

[英]SQL query to get the “latest” value for each location

我認為這是一個簡單的解決方法,現在已經有一段時間了。 現在我需要你們的幫助。

在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查詢中所建議的那樣獲得最新價格 ),但我無法使其工作。 甚至沒有額外的“在最后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中無法實現。

或者還有其他方法嗎? 所有幫助贊賞。

您可以使用以下語法更正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分鍾... oops!

再次編輯:忘記這是針對Informix數據庫...為where子句提供了MSSQL語法。

您需要在子選擇中命名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。

我選擇創建一個單行表'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)的行。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM