【问题标题】:Getting most recent data if data for the day is not available with MySQL如果当天的数据不适用于 MySQL,则获取最新数据
【发布时间】:2020-12-31 21:25:22
【问题描述】:

我有一个大型 SQL 查询 (MySQL 5.7.32),它获取各种数据,并且包括特定日期的定价数据,如果这一天有可用的价格数据。通过一个简单的 LEFT JOIN 完成:

SELECT *
FROM merchants m CROSS JOIN products p
LEFT JOIN prices mps
    ON m.id = mps.id AND p.article_id = mps.article_id AND mps.DATE = $date

在某些情况下,这一天没有价格。在这种情况下,我想获得最近的可用价格。

这是否可以通过 LEFT JOIN 实现,还是我必须为我的语句添加更多复杂性?

【问题讨论】:

    标签: mysql greatest-n-per-group


    【解决方案1】:

    有可能

    SELECT m.*, t.*
    FROM merchants m
    JOIN (
        SELECT MAX(`date`) as max_date, id
        FROM prices
        WHERE `date` <= ?
        GROUP BY id
    ) t ON t.id = m.id
    

    编辑:两步查询

    假设您的商店每页显示 20 种产品。您可以像这样运行第一个查询:

    SELECT m.*
    FROM merchants m
    WHERE some_criterias
    LIMIT 20 OFFSET 0
    

    然后将第一个查询的结果传递给第二个:

    SELECT m.*, t.*
    FROM merchants m
    JOIN (
        SELECT MAX(`date`) as max_date, p.merchant_id
        FROM prices p
        AND merchant_id IN (?, ?, ?...)
        WHERE `date` <= ?
        GROUP BY id
    ) t ON t.merchant_id = m.id
    

    【讨论】:

    • 有趣的方法。我可能需要提到价格表有 300M 行。此查询似乎使用
    • 在这里您可以找到我的查询的基准:kristiannielsen.livejournal.com/6745.html,您可以看到它具有最佳性能。如果您的表有 300M 行,您可以将该过程拆分为 2 个查询。获取产品列表的第一个查询和使用此产品列表的第二个查询(我的答案之一)。我要编辑我的答案。
    • 如何将产品列表传递给第二个查询?我不能使用中间件,因为这是在 Grafana 中使用的查询。
    • 也许你可以创建一个聚合表,你可以每天或每小时重建一个。在此表中,您将输入SELECT MAX(`date`) as max_date, id FROM prices WHERE `date` &lt;= ? GROUP BY id 的结果,然后连接会快很多。
    • 在 DATE、SKU、MERCHANT_ID 上有一个索引(唯一)。您是否相信额外的单独索引日期会显着帮助?我现在实现了一个每晚更新该表的存储过程。谢谢你的帮助。也请考虑支持这个问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-05
    • 2013-01-20
    • 2015-04-12
    • 1970-01-01
    • 2021-01-02
    • 2017-08-27
    相关资源
    最近更新 更多