【问题标题】:Get closest value lower than a specific value and group by获取低于特定值的最接近值并分组
【发布时间】:2015-01-26 21:23:43
【问题描述】:

是否有可能使用没有连接的组函数获得低于特定值的最接近值?

date          productId    stock
2014-12-27    1            10
2014-12-31    1            20
2015-01-05    1            30
2014-12-28    2            10
2015-01-04    2            20

该值例如是日期,应该低于2015-01-01,但最高的日期值和结果应该按库存囊排序,所以结果应该是:

date          productId    stock
2014-12-28    2            10
2014-12-31    1            20

当然,这可以通过连接来解决,但是在大表中连接速度较慢,不是吗?

【问题讨论】:

  • 不,这是不正确的,因为我对可能是任何东西的股票价值感兴趣。
  • 对不起,我认为比我读的要快。您能否发布您的 sql,您尝试过的内容等以澄清?
  • 我更改了一些日期以使其更有意义。我只能想象一个带有SELECT product_id, stock FROM table LEFT JOIN (SELECT product_id, stock FROM table WHERE date<'2015-01-01' LIMIT 0,1) as table2 ON table.product_id=table2.product_d 的解决方案,但这是对大表的缓慢查询。
  • SELECT date, productId, stock FROM table GROUP BY date, productid, stock HAVING date < '2015-01-04' ORDER BY stock ASC 怎么样?
  • 如果我应该运行这个查询,我会得到所有低于 2015-01-04 的值,但我只会得到低于特定日期的最大值。

标签: mysql


【解决方案1】:

对于每个不同的产品 ID,您似乎正在寻找 2014 年的最后一天。

你这样做

             SELECT MAX(date) date, product_id   
               FROM yourtable
              WHERE date < '2015-01-01'
           GROUP BY product_id

这会为您提供date, product_id 的集合。 (date, product_id) 上的复合索引将使此查询的评估效率非常高。

然后你 join 到你的主表,就像这样。

SELECT a.*
  FROM yourtable AS a
  JOIN (
             SELECT MAX(date) date, product_id   
               FROM yourtable
              WHERE date < '2015-01-01'
           GROUP BY product_id
       ) AS b USING(date,product_id)
ORDER BY a.product_id, a.date

并检索 2014 年最后一项的详细记录。相同的复合索引将加速 JOIN。

您担心 JOIN 性能,这是合理的。但是可以通过适当的索引来改进它。真的没有比这更好的方法了。

【讨论】:

  • 感谢您的详细回答,我确实担心性能,但没有更好的解决方案。还有一个问题,该表有 5 列,一个 AI,一个日期列和 3 个外键。这取决于查询,但有时我会收到 product_id 和 date 的组合以及 color_id 和 date 的其他时间。由于 product_id 和 color_id 已经是索引,因此在 date 上仅创建一个索引的两个复合索引(date、product_id 和 date、color_id)会更好吗?
  • @Stefan,为了快速满足这种查询,绝对需要正确的复合覆盖索引。 color_id 上的单列索引无助于此类查询。您应该阅读有关 GROUP BY 优化的信息以了解背景。 dev.mysql.com/doc/refman/5.6/en/group-by-optimization.html
  • 我理解这一点,但是获得一个关于 date 和 product_id 的复合索引真的很重要吗
  • @Stefan 在有效满足MAX()...GROUP BY 查询方面,两个单列索引不能替代复合索引。
  • 感谢您的反应!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-20
  • 2012-04-08
  • 1970-01-01
  • 2012-10-30
相关资源
最近更新 更多