【问题标题】:(My)SQL: group rows by a given field and force the newest data to be used in the grouped row(My)SQL:按给定字段对行进行分组,并强制在分组行中使用最新数据
【发布时间】:2014-07-21 17:07:34
【问题描述】:

我有一个发票表,其中存储了每个订单的发票历史记录,因此一个订单可以有多个发票。 但是在日常使用中,我只想选择每个订单的最新发票。

分配给同一订单的两张发票的示例:

invoice_id | order_id | invoice_number | created_at
=====================================================
1          | 42       | 10621          | 2014-05-28
2          | 42       | 10621          | 2014-05-31

我尝试了以下

SELECT * FROM invoices GROUP BY order_id;

它按找到的第一行(最早的发票)对行进行分组。添加 'ORDER BY created_at DESC' 子句不会改变这一点。 有没有办法只获取每个 order_id 的最新行?

【问题讨论】:

    标签: mysql sql select group-by


    【解决方案1】:

    在发票的最大日期使用自联接,按结果分组是不确定的,他们不能保证在查询下面分组的结果顺序应该可以解决问题

    SELECT 
      i.* 
    FROM
      invoices i 
    JOIN 
      (SELECT 
          order_id,
          MAX(created_at) created_at 
        FROM
          invoices 
     GROUP BY order_id) ii 
    ON (
      i.order_id = ii.order_id 
      AND i.created_at = ii.created_at
    )
    

    【讨论】:

    • 我选择这种方法是因为它对其他开发者来说更​​容易理解。
    【解决方案2】:

    这是获取最新数据行的合理方法。注意它不使用group by:

    select i.*
    from invoices
    where not exists (select 1
                      from invoices i2
                      where i2.order_id = i.order_id and i2.created_at > i.created_at
                     );
    

    如果性能是一个问题,您需要在invoices(order_id, created_at) 上建立索引。

    此版本将问题从“为我获取每个订单的最长日期的发票”更改为“为我获取每个订单的发票,这样该订单的其他发票就没有更大的日期”。

    【讨论】:

    • 一种有趣的方法,但我认为如果您第一次偶然发现代码,很难理解查询实际上在做什么。
    猜你喜欢
    • 2021-10-27
    • 1970-01-01
    • 2021-05-08
    • 1970-01-01
    • 2016-02-17
    • 2017-02-15
    • 1970-01-01
    • 2021-09-18
    • 1970-01-01
    相关资源
    最近更新 更多