如何在集合函数的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_CONCATSUBSTRING_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 

覆盖索引是非常有用的。 检查了解更多细节。