【问题标题】:Using MYSQL, SELECT every nth row from a subquery SELECT使用 MYSQL,从子查询 SELECT 中每隔 n 行选择一次
【发布时间】:2018-04-25 02:31:17
【问题描述】:

我有一个超过 300,000 行的表,我想在图表上呈现这些数据,但 300,000 行并不是一次全部必要的。例如,即使某一天可能有 100 行数据,但如果我要显示一整年的数据,我不需要显示所有这些数据。所以我想“细化”数据。

我正在考虑获取所有内容,然后使用脚本删除我不需要的内容,但这似乎在数据库上会更慢更难。

这就是我目前所拥有的。

SET @row_number := 0;
  SELECT @row_number := @row_number + 1 as row_number, 
  price, region, timestamp as row_number FROM pricehistory;

这给了我所有的行和编号。我打算添加一个 where 子句来获取每 1000 行(即每 n 行)这样的

SET @row_number := 0;
SELECT @row_number := @row_number + 1 as row_number, 
  price, region, timestamp as row_number FROM pricehistory 
  WHERE row_number % 1000 = 0;

但由于某种原因,MYSQL 没有将row_number 视为一列。有任何想法吗?我在网上查看了其他解决方案,但它们似乎不适用于 MYSQL。

【问题讨论】:

  • 行有唯一的 ID 吗?
  • 不要费心添加计算列。如果 ID 是连续的,只需使用它即可。它不会那么准确,但这在您的情况下似乎并不重要,好消息是它会更快。另一种方法是使用带有LIMIT x, 1000 的子查询来为您提供间隔。
  • 您不能在 WHERE 子句中使用来自 SELECT 子句的别名;在将 WHERE 应用于原始 FROM 结果之前,这些结果字段基本上不存在。唯一不会对数据库“更难”的方法是它发送的结果更少;否则,它在工作时会更加繁琐。 您也不能在 SELECT 中使用两次相同的别名。
  • @Uueerdo 好的,那么从技术上讲,"@row_number := @row_number + 1" % 1000 = 0 会被识别吗?
  • @RacilHilan 我可能最终会这样做。特别是如果它更快。

标签: php mysql database


【解决方案1】:

正如 Racil 的评论所建议的那样,如果您有一个自动递增的 id 字段,您就可以使用它;但是您已经说过不同日期的数据量可能不同,因此这可能会导致图表非常失真。如果您选择一年中的每 1000 条记录,并且其中一半的行来自最近 3 个月(商业示例中的“假日购物”),则后半年图表实际上将反映一年中的后一个季度。要获得更有用的结果,您最好使用以下方法:

SELECT region, DATE(timestamp) AS theDate
    , AVG(price), MIN(price), MAX(price)
FROM pricehistory
GROUP BY region, theDate
;

【讨论】:

    【解决方案2】:

    看来我不会得到另一个答案,所以我会继续写我想出的解决方案。

    我的数据分布相当均匀,因为它会定期获取价格,因此无需担心。

    这是我的解决方案。

    假设我有 500,000 行,我想显示这些行的子集,比如说 5000 行。 500000/5000 是 100,所以我取 100 并在我的 select 语句中使用它,就像这样 SELECT * FROM pricehistory where id % 100 = 0;

    这是实际代码

    public function getScaleFactor($startDate, $endDate) { $numPricePoints = $this->getNumPricePointsBetweenDates($startDate, $endDate); $scaleFactor = 1; if ($numPricePoints > $this->desiredNumPricePoints) { $scaleFactor = floor($numPricePoints / $this->desiredNumPricePoints); } return $scaleFactor; }

    然后我在 SQL 中使用 $scaleFactor 就像这样 SELECT * FROM pricehistory WHERE id % {$scaleFactor} = 0;

    这不是一个完美的解决方案,因为您并不总是最终得到 5000 行,但我不需要正好 5000 行。我只是想降低数据的分辨率,同时仍然得到一个看起来接近我使用所有 500,000 行的图表。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-06-19
      • 2021-10-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多