在某些情况下,我想要一些列。
列是: point_id,weight(行当前度指数0到7,0是最新行),localdate(YYYYmmdd),tmin(最低温度),tmax(最高温度)和precip_amount(降水量mm)。
条件是:
(localdate> = 20151201 AND localdate< = 20160104)AND
(tmin <0或tmax <0)AND precip_amount&gt; 40
我的目标是根据体重获取最新的行。
我编写了一个工作正常的sql(经过了2.7秒,处理了64.4 MB)。
但是,有没有办法优化我的SQL以便更快地运行?
我的sql:
select a.point_id as point_id , a.weight as min_weight,a.localdate as local_date, a.tmin as temp_min, a.tmax as temp_max, a.precip_amount as precipitation
from table1 a
join (select point_id, min(weight) as min_weight
from
(select point_id, localdate, tmin, tmax, precip_amount,weight
from table1
where (localdate >= 20151201 and localdate <= 20160104) and (tmin < 0 or tmax < 0) and precip_amount > 40
order by weight)
group by point_id) b
on a.point_id = b.point_id and a.weight = b.min_weight
where (a.localdate >= 20151201 and a.localdate <= 20160104) and (a.tmin < 0 OR a.tmax < 0) and a.precip_amount > 40
order by a.weight, a.localdate
答案 0 :(得分:1)
尝试此查询。我已经将关于最小权重的计算移动到子查询。
SELECT a.point_id as point_id,
(SELECT MIN(A2.weight) FROM Table A2
WHERE A2.point_id = A.point_id
AND A2.localdate >= 20151201
AND A2.localdate <= 20160104
AND (A2.tmin < 0 or A2.tmax < 0)
AND A2.precip_amount > 40) AS min_weight,
A.localdate as local_date,
A.tmin as temp_min,
A.tmax as temp_max,
A.precip_amount as precipitation
FROM Table AS A
WHERE A.localdate >= 20151201
AND A.localdate <= 20160104
AND (A.tmin < 0 OR A.tmax < 0)
AND A.precip_amount > 40
ORDER BY A.weight, A.localdate
您也可以尝试使用窗口功能。例如
SELECT T.* FROM
(SELECT A.point_id,
MIN(A.weight) OVER(PARTITION BY A.point_id) AS min_weight,
A.localdate AS local_date,
A.tmin AS temp_min,
A.tmax AS temp_max,
A.precip_amount as precipitation
FROM Table A
WHERE A.localdate >= 20151201
AND A.localdate <= 20160104
AND (A.tmin < 0 OR A.tmax < 0)
AND A.precip_amount > 40) AS T
ORDER BY T.min_weight,
T.localdate
答案 1 :(得分:1)
select *
from
( select a.point_id as point_id , a.weight as min_weight,a.localdate as local_date, a.tmin as temp_min, a.tmax as temp_max, a.precip_amount as precipitation
, row_number() over (partition by point_id order by weight asc) as rn
from table1 a
where (a.localdate >= 20151201 and a.localdate <= 20160104)
and (a.tmin < 0 OR a.tmax < 0)
and a.precip_amount > 40
) tt
where tt.rn = 1
order by tt.weight, tt.localdate
答案 2 :(得分:0)
尝试使用窗口功能:
select point_id, a.weight as min_weight, local_date, temp_min, temp_max,
precip_amount
from (select a.point_id as point_id, a.weight,
a.localdate as local_date, a.tmin as temp_min, a.tmax as temp_max,
a.precip_amount as precipitation,
min(weight) over (partition by point_id) as min_weight
from table1 a
where (a.localdate >= 20151201 and a.localdate <= 20160104) and
(a.tmin < 0 OR a.tmax < 0) and a.precip_amount > 40
) a
where a.weight = w.min_weight
order by a.weight, a.localdate;