sql - 按客户查找最旧的记录?
问题描述
对于我的 SQL Server 2016 项目,我有一个 Orders 表,如下所示,我想创建一个 SQL 查询来显示每个客户/产品的最早订单。今天 Orders 表中有数千个订单,我预计它的规模会增长,所以我希望它表现良好。
目标是输出如下所示:
订单编号 | 客户ID | 产品编号 | 订单号 | 订单量 |
---|---|---|---|---|
123 | 1 | 1 | 2021 年 1 月 1 日 | 50 美元 |
456 | 1 | 2 | 2021 年 1 月 2 日 | 20 美元 |
345 | 2 | 1 | 2021 年 1 月 1 日 | 30 美元 |
今天 Orders 表中的数据如下所示:
订单编号 | 客户ID | 产品编号 | 订单号 | 订单量 |
---|---|---|---|---|
123 | 1 | 1 | 2021 年 1 月 1 日 | 50 美元 |
758 | 1 | 1 | 2021 年 1 月 2 日 | 80 美元 |
563 | 1 | 2 | 2021 年 1 月 3 日 | 74 |
684 | 1 | 2 | 2021 年 1 月 4 日 | 23 |
456 | 1 | 2 | 2021 年 1 月 2 日 | 20 美元 |
345 | 2 | 1 | 2021 年 1 月 1 日 | 30 美元 |
解决方案
规范的方法是使用row_number()
:
select t.*
from (select t.*,
row_number() over (partition by customerid, productid order by orderdt, orderid) as seqnum
from t
) t
where seqnum = 1;
如果索引 on (customerid, productid, orderdt)
,那么相关子查询可能会更快一点:
select t.*
from t
where t.orderdt = (select min(t2.orderdt)
from t t2
where t2.productid = t.productid and t2.customerid = t.customerid
);
或者没有子查询的性能稍差的方法:
select top (1) with ties t.*
from t
order by row_number() over (partition by productid, customerid order by orderdt);
推荐阅读
- javascript - JS - 使用 FileReader 对象时只允许上传一个文件
- html - 如何在移动布局中居中文本?
- javascript - 电子邮件表格适用于我的网站的一个版本,但不适用于另一个版本?
- java - 代理类中的空依赖项
- ios - 如何在更新它显示的对象数组时更新 SwiftUI 中的 ScrollView?
- python - Dask Dataframe .read_csv 不尊重 dtypes
- html - 角材料卡布局
- git - 为什么不能推送第二个克隆存储库?
- dataframe - Spark Streaming Dataframe 执行,有状态,分区本地 groupBy,避免洗牌
- arrays - 从对象数组中提取一个键值对的数组,同时基于另一个键值对进行过滤