问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

MySQL分组查询获取每组最新的一条数据详解(group by)例子解析

创作时间:
作者:
@小白创作中心

MySQL分组查询获取每组最新的一条数据详解(group by)例子解析

引用
CSDN
1.
https://blog.csdn.net/jimn2000/article/details/142348477

在MySQL中,使用GROUP BY子句可以对结果集进行分组,但GROUP BY本身并不能直接用来获取每组最新的一条数据。要实现这个目的,通常需要结合子查询、JOIN操作或者使用窗口函数(在MySQL 8.0及以上版本中支持)。下面我将通过几个例子来详细解释如何获取每组最新的一条数据。

1. 使用子查询和JOIN

假设我们有一个名为orders的表,包含字段id(订单ID)、customer_id(客户ID)、order_date(订单日期)和amount(订单金额)。我们想要获取每个客户的最新订单。

表结构示例:

CREATE TABLE orders (
    id INT AUTO_INCREMENT PRIMARY KEY,
    customer_id INT,
    order_date DATE,
    amount DECIMAL(10, 2)
);

SQL查询:

SELECT o.*
FROM orders o
INNER JOIN (
    SELECT customer_id, MAX(order_date) AS latest_date
    FROM orders
    GROUP BY customer_id
) latest_orders ON o.customer_id = latest_orders.customer_id AND o.order_date = latest_orders.latest_date;

在这个查询中,子查询首先根据customer_id分组,并使用MAX(order_date)来找出每个客户的最晚订单日期。然后,外层查询通过JOIN操作将原表与子查询结果连接起来,确保只选择每个客户的最新订单。

2. 使用窗口函数(MySQL 8.0+)

如果你使用的是MySQL 8.0或更高版本,可以利用窗口函数ROW_NUMBER()来实现相同的功能。

SQL查询:

SELECT *
FROM (
    SELECT *,
           ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY order_date DESC) AS rn
    FROM orders
) ranked_orders
WHERE rn = 1;

这里,ROW_NUMBER()窗口函数为每个customer_id组内的记录分配一个唯一的行号,行号是根据order_date降序排列的。这样,每个组中order_date最新的记录将被赋予行号1。外层查询通过筛选行号为1的记录来获取每个客户的最新订单。

3. 使用变量(不推荐)

虽然不推荐使用变量来处理这类问题,因为它可能导致性能问题和不易于维护的代码,但作为一种可能的方法,这里也简单介绍:

SQL查询:

SELECT t1.*
FROM orders t1
LEFT JOIN orders t2
ON t1.customer_id = t2.customer_id AND t1.order_date < t2.order_date
WHERE t2.customer_id IS NULL;

这个查询通过自连接orders表,并查找没有更晚订单日期的记录来实现。这种方法在数据量较大时可能效率不高。

总结

获取每组最新的一条数据是一个常见的需求,可以通过多种方法实现。推荐使用子查询和JOIN操作或者窗口函数,这些方法更清晰、效率更高。使用变量的方法虽然可行,但通常不是最佳实践。

本文原文来自CSDN

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号