如何在集合函数的MySQL查询中获取分组logging的第一个和最后一个logging?
我正在尝试获取“分组”logging的第一个和最后一个logging。
更确切地说,我正在做这样的查询
SELECT MIN(low_price), MAX(high_price), open, close FROM symbols WHERE date BETWEEN(.. ..) GROUP BY YEARWEEK(date)
但我想得到这个小组的第一个和最后一个logging。 这可以通过做大量的请求,但我有一个相当大的表。
有没有(如果可能,处理时间很less)的方式来做到这一点与MySQL?
你想使用GROUP_CONCAT
和SUBSTRING_INDEX
:
SUBSTRING_INDEX( GROUP_CONCAT(CAST(open AS CHAR) ORDER BY datetime), ',', 1 ) AS open SUBSTRING_INDEX( GROUP_CONCAT(CAST(close AS CHAR) ORDER BY datetime DESC), ',', 1 ) AS close
这避免了昂贵的子查询,我发现通常这个特定的问题更有效率。
查看这两个函数的手册页来理解它们的参数,或者访问这篇文章,其中包括如何在MySQL中进行时间帧转换以获取更多解释的示例。
试试这个以…开头:
Select YearWeek, Date, Min(Low_Price), Max(High_Price) From (Select YEARWEEK(date) YearWeek, Date, LowPrice, High_Price From Symbols S Where Date BETWEEN(.. ..) GROUP BY YEARWEEK(date)) Z Group By YearWeek, Date
下面是这个特定问题的一个很好的具体解决scheme: http : //topwebguy.com/first-and-last-in-mysql-a-working-solution/这几乎就像在MySQL中使用FIRST和LAST一样简单。
我将包括实际提供解决scheme的代码,但您可以查看全文:
SELECT word , (SELECT a.ip_addr FROM article a WHERE a.word = article.word ORDER BY a.updated LIMIT 1) AS first_ip, (SELECT a.ip_addr FROM article a WHERE a.word = article.word ORDER BY a.updated DESC LIMIT 1) AS last_ip FROM notfound GROUP BY word;
假设您想要low_price最低和high_price最高的logging的id,您可以将这两列添加到您的查询中,
SELECT (SELECT id ORDER BY low_price ASC LIMIT 1) low_price_id, (SELECT id ORDER BY high_price DESC LIMIT 1) high_price_id, MIN(low_price), MAX(high_price), open, close FROM symbols WHERE date BETWEEN(.. ..) GROUP BY YEARWEEK(date)
如果效率是一个问题,您应该添加一个'year_week'列,添加一些覆盖索引,并将查询分为两部分。
“year_week”列只是设置为YEARWEEK(date)值的INT,每当更新“date”列时都会更新。 这样你不必为每个查询重新计算它,你可以索引它。
新的覆盖指标应该是这样的。 sorting很重要。 KEY yw_lp_id(year_week,low_price,id),KEY yw_hp_id(year_week,high_price,id)
您应该使用这两个查询
SELECT (SELECT id ORDER BY low_price ASC LIMIT 1) low_price_id, MIN(low_price), open, close FROM symbols WHERE year_week BETWEEN(.. ..) GROUP BY year_week
和
SELECT (SELECT id ORDER BY high_price DESC LIMIT 1) high_price_id, MAX(high_price), open, close FROM symbols WHERE year_week BETWEEN(.. ..) GROUP BY year_week
覆盖索引是非常有用的。 检查了解更多细节。