Mysql SQL查询-仅当值在“0”范围内时获取行;“最后n个记录”;(特定记录)
我有两张桌子,一张国家桌和一张气象桌。我想检索过去15天内没有下雨的所有国家的名称 天气表有一个名为“DayNum”的列,它从1->无穷大开始,每天增加1,这是唯一的。这个表还有一个名为“Rain”的列,它只是一个0或1的布尔值 此外,并非所有国家都是在同一天添加的,因此每个国家的最大DayNum将不同 下表示例(为了可读性,数据被截断): 国家:Mysql SQL查询-仅当值在“0”范围内时获取行;“最后n个记录”;(特定记录),mysql,sql,Mysql,Sql,我有两张桌子,一张国家桌和一张气象桌。我想检索过去15天内没有下雨的所有国家的名称 天气表有一个名为“DayNum”的列,它从1->无穷大开始,每天增加1,这是唯一的。这个表还有一个名为“Rain”的列,它只是一个0或1的布尔值 此外,并非所有国家都是在同一天添加的,因此每个国家的最大DayNum将不同 下表示例(为了可读性,数据被截断): 国家: ID Name 1 USA 2 Cananda 3 Brazil 天气
ID Name
1 USA
2 Cananda
3 Brazil
天气
ID Country_id DayNum Rain
1 1 1 0
2 1 2 0
3 1 3 1
以下是我当前的查询尝试(已为此工作了几天):
我认为这应该行得通,但我有严重的性能问题。我需要编写的实际查询处理不同的数据(相同的确切概念)和数百万行。这个查询似乎以指数速度变慢
有人能提供一些建议吗
我的另一个想法是,以某种方式限制连接仅获取前15条记录(同时按weather.day_num排序),但我还没有找到在连接中实现这一点的方法(如果可能的话)。您对降雨量不感兴趣,只关心它是否存在,所以
select * from countries
left join
(
select weather.country_id
from weather
inner join
(select country_id, MAX(daynum) as maxdaynum from weather group by country_id) maxday
on weather.country_id = maxday.country_id
and weather.daynum>maxday.maxdaynum-3
where rain=1
) rainy
on countries.id = rainy.country_id
where country_id is null
我认为您已经对表进行了适当的索引您没有在表中包含任何有关索引的信息,但我敢打赌您遇到的性能问题与“国家/地区名称”字段中的group by相关。如果该列没有索引,它肯定会解释您的性能问题 话虽如此,这种情况可能需要子查询而不是内部联接。我很想这样写查询:
SELECT countries.id, countries.name
FROM countries
INNER JOIN
(
SELECT country_id
FROM weather
GROUP BY country_id
HAVING weather.daynum > (MAX(weather.day_num) - 15) AND SUM(weather.rain) = 0
) AS weather
ON weather.country_id = countries.id;
也许您可以使用一个简单的变量来存储所需的min daynum?我不是mySQL开发人员,但我认为这样做可以达到以下目的:
SELECT @minDaynum := (MAX(daynum)-15) FROM weather;
SELECT DISTINCT countries.name
FROM weather
INNER JOIN countries ON weather.country_id = countries.id
WHERE
weather.daynum >= @minDaynum AND
weather.rain = 1;
编辑>>如果只有一个变量不适合您的情况,可以尝试使用临时表来加快速度(但不确定mysql中临时表的性能是否真的很好…:
在这里,我只是将每个国家的最小daynum存储在临时表中。希望对你有帮助
我有两张桌子,一张国家桌和一张气象桌。我想检索过去15天内没有下雨的所有国家的名称
给你:
SELECT * FROM Country
WHERE
NOT EXISTS (
SELECT * FROM Weather
WHERE
Rain = 1
AND DayNum >= 2
AND Country_id = Country.ID
);
在计划英语中:对于每个国家,检查是否有比给定天数新的雨天。如果有,则从结果中删除该国家
将2
替换为15天前的天数。在{Country\u id,DayNum,Rain}
上建立索引,以获得良好的性能。不幸的是,MySQL不太可能以最佳方式执行此查询,但是只有这么多国家,所以嵌套循环应该不会太糟糕,因为DBMS应该能够以单个索引搜索的方式执行内部查询
P>可选地,考虑将它改写为连接,例如:
SELECT Country.*
FROM Country LEFT JOIN Weather
ON Country_id = Country.ID
AND Rain = 1
AND DayNum >= 2
GROUP BY Country.ID, Country.Name
HAVING MAX(Rain) IS NULL OR MAX(Rain) = 0;
一个有效的SQL FIDLE示例是。这给了我一个错误:错误1111(HY000):组函数的使用无效。我认为这是由于在WHERE子句中使用聚合函数(max,sum)而不是HAVING子句造成的?我需要熟悉declare和BEGIN…END,但我认为这不起作用,因为我所有的国家都有不同的max DayNum(我想我的示例在这个意义上有点弱)。所以我想如果美国比其他国家早15天加入,我会得到糟糕的结果。我更新了我的OP来反映这一点。我只优化了max(daynum),因为我认为它们是一样的。。。我会重新编辑的in@podiluska提出了这一点(并编辑了他们的帖子)。问题是并非每个国家的MAX(daynum)值都相同。如果他们这样做的话,这可能会起作用。
SELECT * FROM Country
WHERE
NOT EXISTS (
SELECT * FROM Weather
WHERE
Rain = 1
AND DayNum >= 2
AND Country_id = Country.ID
);
SELECT Country.*
FROM Country LEFT JOIN Weather
ON Country_id = Country.ID
AND Rain = 1
AND DayNum >= 2
GROUP BY Country.ID, Country.Name
HAVING MAX(Rain) IS NULL OR MAX(Rain) = 0;