[英]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.