SQL Server 2017如何获取每种物料的最新3条订单数据
问题:SQL Server 2017中获取每种物料的最新3条订单
现有数据表
orders表
| ORDERNO | ORDER_DATE | MAT1 | Menge |
|---|---|---|---|
| 3912 | 09-09-1996 00:00:00 | 1 | 1020 |
| 3039 | 17-07-1995 00:00:00 | 1 | 30000 |
| 2985 | 27-06-1995 00:00:00 | 1 | 100000 |
| 2879 | 20-04-1995 00:00:00 | 1 | 100000 |
| 2735 | 06-02-1995 00:00:00 | 1 | 100000 |
| 3000 | 29-06-1995 00:00:00 | 2 | 30000 |
| 2986 | 27-06-1995 00:00:00 | 2 | 100000 |
| 2927 | 18-05-1995 00:00:00 | 2 | 100000 |
| 2794 | 08-03-1995 00:00:00 | 2 | 100000 |
| 2738 | 07-02-1995 00:00:00 | 2 | 100000 |
| 2652 | 06-01-1995 00:00:00 | 2 | 30000 |
| 3082 | 09-08-1995 00:00:00 | 3 | 30000 |
| 2717 | 31-01-1995 00:00:00 | 3 | 30000 |
| 806 | 28-10-1991 00:00:00 | 3 | 20000 |
| 693 | 02-07-1991 00:00:00 | 3 | 15000 |
| 29008 | 13-02-2023 09:02:02 | 4 | 324000 |
| 28871 | 07-12-2022 10:27:12 | 4 | 580000 |
| 28787 | 03-11-2022 13:46:42 | 4 | 300000 |
| 28726 | 12-10-2022 09:28:18 | 4 | 580000 |
| 28676 | 07-09-2022 11:33:53 | 4 | 580000 |
| 28661 | 31-08-2022 15:26:44 | 4 | 360000 |
materials表
| nr | price | weight |
|---|---|---|
| 1 | 0.9797 | 0.0740 |
| 2 | 0.0000 | 0.0000 |
| 3 | 0.0919 | 0.0740 |
| 4 | 0.0000 | 0.0850 |
期望结果
| nr | price | weight | ORDERNO | ORDER_DATE | MAT1 | Menge |
|---|---|---|---|---|---|---|
| 1 | 0.9797 | 0.0740 | 3912 | 09-09-1996 00:00:00 | 1 | 1020 |
| 1 | 0.9797 | 0.0740 | 3039 | 17-07-1995 00:00:00 | 1 | 30000 |
| 1 | 0.9797 | 0.0740 | 2985 | 27-06-1995 00:00:00 | 1 | 100000 |
| 2 | 0.0000 | 0.0000 | 3000 | 29-06-1995 00:00:00 | 2 | 30000 |
| 2 | 0.0000 | 0.0000 | 2986 | 27-06-1995 00:00:00 | 2 | 100000 |
| 2 | 0.0000 | 0.0000 | 2927 | 18-05-1995 00:00:00 | 2 | 100000 |
已尝试代码(获取单条最新订单)
select * from Material m join ( select o.ORDERNO, max(o.ORDER_DATE) as ORDER_DATE, o.MAT1, o.Menge from orders o group by o.ORDERNO, o.MAT1, o.Menge) as t1 on t1.MAT1 = m.NR
解决方案
在SQL Server中,使用窗口函数ROW_NUMBER()可以轻松实现分组取前N条数据的需求,具体代码如下:
SELECT m.nr, m.price, m.weight, o.ORDERNO, o.ORDER_DATE, o.MAT1, o.Menge FROM materials m INNER JOIN ( SELECT *, -- 按物料分组,按订单日期降序编号,每组内最新的订单排第1 ROW_NUMBER() OVER (PARTITION BY MAT1 ORDER BY ORDER_DATE DESC) AS row_num FROM orders ) o ON m.nr = o.MAT1 WHERE o.row_num <= 3 -- 筛选每组内前3条最新订单 ORDER BY m.nr, o.row_num; -- 按物料编号和行号排序,确保结果顺序符合预期
代码说明
- 子查询中通过
PARTITION BY MAT1将订单按物料分组,ORDER BY ORDER_DATE DESC让每组内的订单按日期从新到旧排序,ROW_NUMBER()为每组内的订单分配唯一的行号。 - 关联
materials表后,通过WHERE o.row_num <=3筛选出每组的前3条最新订单。 - 最后按物料编号和行号排序,保证结果的展示顺序和期望一致。
内容的提问来源于stack exchange,提问作者Julius
相关产品推荐
相关产品推荐

