SQL Server:如何将统计客户数量的查询改为显示具体客户ID
如何修改SQL语句以显示符合条件的客户ID?
交易数据
| CustomerID | Trans_date |
|---|---|
| C001 | 01-sep-22 |
| C001 | 04-sep-22 |
| C001 | 14-sep-22 |
| C002 | 03-sep-22 |
| C002 | 01-sep-22 |
| C002 | 18-sep-22 |
| C002 | 20-sep-22 |
| C003 | 02-sep-22 |
| C003 | 28-sep-22 |
| C004 | 08-sep-22 |
| C004 | 18-sep-22 |
需求与问题
需要筛选出同时存在两段交易记录的客户:
- 2022年8月29日至9月4日有交易
- 2022年9月5日至9月11日有交易
原SQL语句仅返回符合条件的客户数量(结果为2),但无法查看具体的客户ID,需调整语句以显示这些ID。
原SQL语句
select count(distinct CustomerID) from trydata where CustTrans between '2022-09-01' and '2022-09-04' and CustomerID in (select distinct CustomerID from trydata where CustTrans between '2022-09-12' and '2022-09-18')
注意:原SQL的日期条件和需求不匹配——原语句实际筛选的是「9月1日-4日有交易」且「9月12日-18日有交易」的客户,而非需求中的时间段。如果要贴合原始需求,需同步修正日期范围。
修改后的SQL语句
方法1:直接返回客户ID(基于原逻辑调整)
把原语句中的count(distinct CustomerID)替换为distinct CustomerID,即可得到具体的客户ID:
select distinct CustomerID from trydata -- 修正为需求的第一个时间段 where CustTrans between '2022-08-29' and '2022-09-04' and CustomerID in (select distinct CustomerID from trydata -- 修正为需求的第二个时间段 where CustTrans between '2022-09-05' and '2022-09-11')
如果沿用原SQL的日期条件(9月1日-4日、9月12日-18日),则去掉日期修正部分即可,执行后会返回C001和C002。
方法2:使用EXISTS子查询(性能更优)
针对大数据量场景,EXISTS的执行效率通常优于IN,写法如下:
select distinct t1.CustomerID from trydata t1 where t1.CustTrans between '2022-08-29' and '2022-09-04' and exists (select 1 from trydata t2 where t2.CustomerID = t1.CustomerID and t2.CustTrans between '2022-09-05' and '2022-09-11')
方法3:分组聚合筛选
通过分组后统计两段时间内的交易次数,筛选同时满足条件的客户:
select CustomerID from trydata where CustTrans between '2022-08-29' and '2022-09-11' group by CustomerID having -- 第一个时间段有交易 sum(case when CustTrans between '2022-08-29' and '2022-09-04' then 1 else 0 end) > 0 -- 第二个时间段有交易 and sum(case when CustTrans between '2022-09-05' and '2022-09-11' then 1 else 0 end) > 0
内容的提问来源于stack exchange,提问作者tasya fauzia fitriasari
相关产品推荐
相关产品推荐

