[英]How do I use the MAX function over three tables?
所以,我有一個SQL查詢的問題。
這是關於獲取德國城市的天氣數據。 我有4個表:staedte(主鍵loc_id的城市),gehoert_zu(包含城市鑰匙和最靠近這個城市的氣象站的鑰匙(stations_id)),wettermessung(包含所有的天氣信息和車站的鍵值)和wetterstation(包含站點鍵和位置)。 我正在使用PostgreSQL
表格如下:
wetterstation
s_id[PK] standort lon lat hoehe
----------------------------------------
10224 Bremen 53.05 8.8 4
wettermessung
stations_id[PK] datum[PK] max_temp_2m ......
----------------------------------------------------
10224 2013-3-24 -0.4
staedte
loc_id[PK] name lat lon
-------------------------------
15 Asch 48.4 9.8
gehoert_zu
loc_id[PK] stations_id[PK]
-----------------------------
15 10224
我想要做的是在指定日期(可能是整月或一天)獲得具有(例如)最高溫度的城市名稱。 由於天氣數據被綁定到一個站點,我實際上需要獲取該站點的ID,然后只選擇該站點城市對應的一個。 一個可能的問題是:“六月哪個城市最熱?” 而且,最高的測量溫度是在10224號站點。因此我想得到Asch這個城市。 到目前為止我得到的是這個
SELECT name, MAX (max_temp_2m)
FROM wettermessung, staedte, gehoert_zu
WHERE wettermessung.stations_id = gehoert_zu.stations_id
AND gehoert_zu.loc_id = staedte.loc_id
AND wettermessung.datum BETWEEN '2012-8-1' AND '2012-12-1'
GROUP BY name
ORDER BY MAX (max_temp_2m) DESC
LIMIT 1
結果有兩個問題:1)它花了很長時間。 表格不是那么大(城市有大約70k條目),但需要1到7分鍾才能完成任務(取決於時間跨度)2)它總是生產同一個城市,我很確定它不是正確的一個。
我希望我能夠清楚地解釋我的問題,我會很樂意提供任何幫助。 提前致謝 ! :d
如果您想獲得每個城市的最高溫度,請使用以下聲明:
SELECT * FROM (
SELECT gz.loc_id, MAX(max_temp_2m) as temperature
FROM wettermessung as wm
INNER JOIN gehoert_zu as gz
ON wm.stations_id = gz.stations_id
WHERE wm.datum BETWEEN '2012-8-1' AND '2012-12-1'
GROUP BY gz.loc_id) as subselect
INNER JOIN staedte as std
ON std.loc_id = subselect.loc_id
ORDER BY subselect.temperature DESC
使用此語句可以獲得溫度最高的城市(僅1個城市):
SELECT * FROM(
SELECT name, MAX(max_temp_2m) as temp
FROM wettermessung as wm
INNER JOIN gehoert_zu as gz
ON wm.stations_id = gz.stations_id
INNER JOIN staedte as std
ON gz.loc_id = std.loc_id
WHERE wm.datum BETWEEN '2012-8-1' AND '2012-12-1'
GROUP BY name
ORDER BY MAX(max_temp_2m) DESC
LIMIT 1) as subselect
ORDER BY temp desc
LIMIT 1
出於性能原因,總是使用顯式連接作為LEFT,RIGHT,INNER JOIN並避免使用具有分隔表名的連接,因此您的sql serevr不會猜測您的表引用。
這是如何獲得具有最高,最低,最大,最小,無論價值的項目的一般示例。 您可以根據您的具體情況進行調整。
select fred, barney, wilma
from bedrock join
(select fred, max(dino) maxdino
from bedrock
where whatever
group by fred ) flinstone on bedrock.fred = flinstone.fred
where dino = maxdino
and other conditions
我建議你使用一致的命名約定。 每行持有單個項目的表的奇異術語是一個很好的約定。 你只有表破壞這是staedte
。 應該是stadt
。
我建議使用station_id
一致,而不是要么s_id
和stations_id
。
在這些前提下,針對您的問題:
...獲取具有...指定日期最高溫度的城市名稱
SELECT s.name, w.max_temp_2m
FROM (
SELECT station_id, max_temp_2m
FROM wettermessung
WHERE datum >= '2012-8-1'::date
AND datum < '2012-12-1'::date -- exclude upper border
ORDER BY max_temp_2m DESC, station_id -- id as tie breaker
LIMIT 1
) w
JOIN gehoert_zu g USING (station_id) -- assuming normalized names
JOIN stadt s USING (loc_id)
使用顯式JOIN
條件可獲得更好的可讀性和維護性。
使用表別名來簡化查詢。
使用x >= a AND x < b
來包含下邊框並排除上邊框,這是常見的用例。
首先聚合並選擇具有最高溫度的工作站,然后再加入其他表以檢索城市名稱。 更簡單,更快捷。
在給定時間范圍內多個“wettermessungen”綁定在max_temp_2m
上時,您沒有指定要執行的操作。 我添加了station_id
作為決勝局,這意味着如果有多個合格站,將會一致地選擇id最低的站。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.