我正在尝试获取“分组”记录的第一条和最后一条记录。
更准确地说,我正在做这样的查询
SELECT MIN(low_price), MAX(high_price), open, close
FROM symbols
WHERE date BETWEEN(.. ..)
GROUP BY YEARWEEK(date)
但我想获得该组的第一条和最后一条记录。它可以通过做大量的请求来完成,但我有一张很大的桌子。
是否有(如果可能的话,处理时间较短)方法可以用 MySQL 做到这一点?
我正在尝试获取“分组”记录的第一条和最后一条记录。
更准确地说,我正在做这样的查询
SELECT MIN(low_price), MAX(high_price), open, close
FROM symbols
WHERE date BETWEEN(.. ..)
GROUP BY YEARWEEK(date)
但我想获得该组的第一条和最后一条记录。它可以通过做大量的请求来完成,但我有一张很大的桌子。
是否有(如果可能的话,处理时间较短)方法可以用 MySQL 做到这一点?
你想使用GROUP_CONCAT
and 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
这是针对这个特定问题的一个很好的特定解决方案:http: //topwebguy.com/first-and-last-in-mysql-a-working-solution/ 它几乎就像在 MySQL 中使用 FIRST 和 LAST 一样简单。
我将包含实际提供解决方案的代码,但您可以查看全文:
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 的记录的 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' 列时更新。这样你就不必为每个查询重新计算它,你可以索引它。
新的覆盖索引应如下所示。顺序很重要。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
覆盖索引非常有用。查看此内容以获取更多详细信息。