假设我在名为wx_data的表格中有以下数据(临时值对于此处列出的日期和城市不准确)
city, wx_date, avg_temp
Kansas City, 2012-11-01, 28
Kansas City, 2012-11-02, 42
Kansas City, 2012-11-03, 86
Kansas City, 2012-11-04, 39
Kansas City, 2012-11-05, 27
Kansas City, 2012-11-06, 65
Kansas City, 2012-11-07, 62
Kansas City, 2012-11-08, 55
Kansas City, 2012-11-09, 95
Kansas City, 2012-11-10, 90
Kansas City, 2012-11-11, 29
Saint Louis, 2012-11-01, 88
Saint Louis, 2012-11-02, 42
Saint Louis, 2012-11-03, 30
Saint Louis, 2012-11-04, 60
Saint Louis, 2012-11-05, 85
Saint Louis, 2012-11-06, 65
Saint Louis, 2012-11-07, 62
Saint Louis, 2012-11-08, 32
Saint Louis, 2012-11-09, 80
Saint Louis, 2012-11-10, 80
Saint Louis, 2012-11-11, 33
我有一个查询,它确定每个城市的最大值和最小值,并返回标记为低和高的行,具体取决于给定日期的温度是否落在最高或最低观测温度的15%之内(在数据集)。
select
temp.city,
wx_date,
avg_tmp,
if(avg_tmp >=.85*temp.High, "High", "Low")
from
wx_data
inner join (select city,
Min(avg_tmp) as Low,
Max(avg_tmp) as High
from
wx_data
where
wx_date between '2012-11-02' and '2013-12-01'
group by city) as temp
on wx_data.city=temp.city
where
avg_tmp >= .85 * temp.High
or avg_tmp <= 1.15 * temp.Low
order by
city,
wx_date;
我想修改查询以便返回上面的结果,但它只返回状态从低变为高的行,反之亦然。因此,我不希望连续几天看到数据返回低或高状态。
我该怎么做?
为了澄清,现在我的查询返回以下数据:
Kansas City November, 01 2012 28 Low
Kansas City November, 03 2012 86 High
Kansas City November, 04 2012 29 Low
Kansas City November, 05 2012 27 Low
Kansas City November, 09 2012 95 High
Kansas City November, 10 2012 90 High
Kansas City November, 11 2012 29 Low
Saint Louis November, 01 2012 33 Low
Saint Louis November, 02 2012 88 High
Saint Louis November, 03 2012 87 High
Saint Louis November, 05 2012 85 High
Saint Louis November, 08 2012 32 Low
Saint Louis November, 09 2012 80 High
Saint Louis November, 10 2012 80 High
Saint Louis November, 11 2012 33 Low
我只希望它返回按城市从高状态转换为低状态的行,以及反向Versa,因此如果我的查询正确,则应返回以下9行。
Kansas City November, 01 2012 28 Low
Kansas City November, 03 2012 86 High
Kansas City November, 04 2012 29 Low
Kansas City November, 09 2012 95 High
Kansas City November, 11 2012 29 Low
Saint Louis November, 02 2012 88 High
Saint Louis November, 08 2012 32 Low
Saint Louis November, 09 2012 80 High
Saint Louis November, 11 2012 33 Low
有关数据和查询结果的示例,请参阅http://www.sqlfiddle.com/#!2/384fb/1。
答案 0 :(得分:2)
核心查询不会更像这样 - 根据你的定义......?
SELECT city
, MAX(avg_temp) max_temp
, 0.85*MAX(avg_temp) max_threshold
, MIN(avg_temp) min_temp
, 1.15 * MIN(avg_temp) min_threshold
FROM wx_data
GROUP
BY city ;
+-------------+----------+---------------+----------+---------------+
| city | max_temp | max_threshold | min_temp | min_threshold |
+-------------+----------+---------------+----------+---------------+
| Kansas City | 95 | 80.75 | 27 | 31.05 |
| Saint Louis | 88 | 74.80 | 30 | 34.50 |
+-------------+----------+---------------+----------+---------------+
......等等......
SELECT x.*
, CASE WHEN x.avg_temp BETWEEN y.min_temp AND y.min_threshold THEN 'Low'
WHEN x.avg_temp BETWEEN y.max_threshold AND y.max_temp THEN 'High'
ELSE ''
END status
FROM wx_data x
JOIN
( SELECT city
, MAX(avg_temp) max_temp
, 0.85*MAX(avg_temp) max_threshold
, MIN(avg_temp) min_temp
, 1.15 * MIN(avg_temp) min_threshold
FROM wx_data GROUP BY city
) y
ON y.city = x.city;
+-------------+------------+----------+--------+
| city | wx_date | avg_temp | status |
+-------------+------------+----------+--------+
| Kansas City | 2012-11-01 | 28 | Low |
| Kansas City | 2012-11-02 | 42 | |
| Kansas City | 2012-11-03 | 86 | High |
| Kansas City | 2012-11-04 | 39 | |
| Kansas City | 2012-11-05 | 27 | Low |
| Kansas City | 2012-11-06 | 65 | |
| Kansas City | 2012-11-07 | 62 | |
| Kansas City | 2012-11-08 | 55 | |
| Kansas City | 2012-11-09 | 95 | High |
| Kansas City | 2012-11-10 | 90 | High |
| Kansas City | 2012-11-11 | 29 | Low |
| Saint Louis | 2012-11-01 | 88 | High |
| Saint Louis | 2012-11-02 | 42 | |
| Saint Louis | 2012-11-03 | 30 | Low |
| Saint Louis | 2012-11-04 | 60 | |
| Saint Louis | 2012-11-05 | 85 | High |
| Saint Louis | 2012-11-06 | 65 | |
| Saint Louis | 2012-11-07 | 62 | |
| Saint Louis | 2012-11-08 | 32 | Low |
| Saint Louis | 2012-11-09 | 80 | High |
| Saint Louis | 2012-11-10 | 80 | High |
| Saint Louis | 2012-11-11 | 33 | Low |
+-------------+------------+----------+--------+
编辑: ......并进一步扩展这个想法(用sqlfiddle数据集进行比特)......
SELECT a.city,a.wx_date,a.avg_tmp FROM
(
SELECT x.*
, IF(@prev = CASE WHEN x.avg_tmp BETWEEN y.min_tmp AND y.min_threshold THEN 'Low'
WHEN x.avg_tmp BETWEEN y.max_threshold AND y.max_tmp THEN 'High'
ELSE ''
END, @i := 0, @i:=1) flag
, @prev := CASE WHEN x.avg_tmp BETWEEN y.min_tmp AND y.min_threshold THEN 'Low'
WHEN x.avg_tmp BETWEEN y.max_threshold AND y.max_tmp THEN 'High'
ELSE ''
END status
FROM wx_data x
JOIN
( SELECT city
, MAX(avg_tmp) max_tmp
, 0.85*MAX(avg_tmp) max_threshold
, MIN(avg_tmp) min_tmp
, 1.15 * MIN(avg_tmp) min_threshold
FROM wx_data GROUP BY city
) y
ON y.city = x.city
JOIN (SELECT @i:=NULL,@prev:=NULL) vars
ORDER
BY city,wx_date
) a
WHERE flag = 1 AND status <> '';
答案 1 :(得分:1)
假设您的查询正确,并且您只想显示高/低值更改的行:
select city, wx_date, avg_tmp, hi_lo
from (
select temp.city, wx_date, avg_tmp,
if(avg_tmp >=.85*temp.High,"High","Low") hi_lo,
@prevHiLo = (avg_tmp >=.85*temp.High and @prevCity = temp.city) same_as_prev,
@prevHiLo := (avg_tmp >=.85*temp.High),
@prevCity := temp.city
from wx_data
inner join
(select city, Min(avg_tmp) as Low, Max(avg_tmp) as High from wx_data
where (wx_date between '2012-11-02' and '2013-12-01') group by city)
as temp on wx_data.city=temp.city
where (avg_tmp >= .85*temp.High or avg_tmp <= 1.15*temp.Low)
order by city, wx_date
) t1
where same_as_prev = 0
order by city, wx_date
http://www.sqlfiddle.com/#!2/b6f42/2
CITY WX_DATE AVG_TMP HI_LO
Kansas City November, 03 2012 00:00:00+0000 86 High
Kansas City November, 04 2012 00:00:00+0000 29 Low
Kansas City November, 09 2012 00:00:00+0000 95 High
Kansas City November, 11 2012 00:00:00+0000 29 Low
Saint Louis November, 02 2012 00:00:00+0000 88 High
Saint Louis November, 08 2012 00:00:00+0000 32 Low
Saint Louis November, 09 2012 00:00:00+0000 80 High
Saint Louis November, 11 2012 00:00:00+0000 33 Low