mysql查询,满足条件返回行
假设我在一个名为wx_data的表格中有以下数据,临时数据与此处列出的日期和城市不准确mysql查询,满足条件返回行,mysql,Mysql,假设我在一个名为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 Kan
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
我有一个查询,它确定每个城市的最大值和最小值,并返回标记为Low和High的行,这取决于给定一天的温度是否在数据集中观察到的最高或最低温度的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;
我只希望它按城市返回从高到低状态交换的行,反之亦然,因此如果我得到正确的查询,应该返回以下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
有关数据和查询结果的示例,请参见。根据您的定义,核心查询不是更像这样吗
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 <> '';
假设您的查询是正确的,并且只希望显示高/低值发生更改的行:
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
你能再详细说明一下你的问题吗?您希望查询返回的确切内容是什么?您还可以根据样本日期查询一整年,其中包括所有季节。。。所以,我认为高低温的基础并没有任何真正的意义。。。而不是说基于普通月份的平均值。我只是快速输入数据进行测试。因此,请不要关注数据,而要关注实际问题,我同意,我会关注比一年更紧的时间间隔。我的算法可能会出错,但在我看来,您的查询只测试接近“低”的程度!?!?!我添加了sqlfiddle链接,因此您可以看到查询工作。请注意,SQLFIDLE中的数据与我在这里发布的数据略有不同,我认为一行或两行是不同的。如果你的更好,我完全赞成。但我的核心问题仍然是我问的问题。我知道你做了什么。现在的问题是,我如何调整它,以便它检查前几天的状态,如果它从前一天更改,则返回?Fy,我当前的查询只返回标记为“低”或“高”的行,如果中间的某行为55或60,则不返回该行。有一个问题,我查看了SQL fiddle数据集,不明白为什么会返回11月5日的圣路易斯记录。在第2次和第5次之间,它并没有转变为一个较低的事件。我想这可能是因为他们之间的那一天公布的结果超出了15%的标准,导致@prev被重新设置。如果这不是你想要的,那么我认为你已经把WHERE状态放在wx_data x之后了。问题是,我认为MySQL不知道当时的状态如何,所以你必须把它写出来,例如,当x.avg_tmp等出现时,在什么情况下。
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
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