求助:使用MIN()函数筛选同一客户服务日最小TX_ID数据无结果
问题
我有一个数据集,同一客户在同一服务日期下有多条数据记录,希望仅返回TX_ID最小的行。尝试用子查询结合MIN()函数实现,但查询未返回任何数据。
当前数据
| TX_ID | CUSTOMER_ID | SERVICE_DATE | SERV_TECH_ID | TOTAL_CHG |
|---|---|---|---|---|
| 901772 | 12345 | 3/6/23 | 1125 | 250 |
| 901773 | 12345 | 3/6/23 | 1125 | 75 |
| 901774 | 12345 | 3/6/23 | 1125 | 50 |
期望结果
| TX_ID | CUSTOMER_ID | SERVICE_DATE | SERV_TECH_ID | POS_ID | LOC_ID | REV_CODE | TOTAL_CHG |
|---|---|---|---|---|---|---|---|
| 901772 | 12345 | 3/6/23 | 1125 | 3081 | 100 | 4425 | 250 |
当前使用的查询语句(无返回结果)
SELECT TX_ID ,at.CUSTOMER_ID ,at.SERVICE_DATE ,SERV_TECH_ID ,TOTAL _CHG FROM ARPB_TRANSACTIONS at INNER JOIN ( SELECT CUSTOMER_ID, MIN(TX_ID) AS TX, SERVICE_DATE FROM ARPB_TRANSACTIONS GROUP BY CUSTOMER_ID, SERVICE_DATE ) oq ON at.CUSTOMER_ID = oq.CUSTOMER_ID AND TX_ID = oq.TX WHERE at.CUSTOMER_ID = '12345' AND at.SERVICE_DATE = '3/6/23' AND SERV_TECH_ID = '1125' AND VOID_DATE IS NULL GROUP BY at.CUSTOMER_ID ,at.TX_ID ,at.SERVICE_DATE ,SERV_TECH_ID ,TOTAL_TOTAL
问题分析与解决方案
原查询的问题点
- 连接条件缺失:子查询按
CUSTOMER_ID和SERVICE_DATE分组,但连接时只匹配了CUSTOMER_ID和TX_ID,未关联SERVICE_DATE。若存在其他日期下相同客户的最小TX_ID,会导致匹配错误,内连接过滤掉有效数据。 - 字段拼写错误:
- SELECT中的
TOTAL _CHG多了空格,应为TOTAL_CHG - GROUP BY中的
TOTAL_TOTAL应为TOTAL_CHG(与SELECT字段一致)
- SELECT中的
- 多余的GROUP BY:外层查询不需要分组,子查询已经筛选出每个客户+日期组的最小TX_ID,关联后只会返回唯一行。
- 日期格式隐患:如果
SERVICE_DATE是日期类型,字符串'3/6/23'可能因数据库日期格式设置不匹配导致过滤失败,建议使用标准格式如'2023-03-06'。
修正后的查询(基于原逻辑)
SELECT TX_ID, at.CUSTOMER_ID, at.SERVICE_DATE, SERV_TECH_ID, TOTAL_CHG, POS_ID, LOC_ID, REV_CODE FROM ARPB_TRANSACTIONS at INNER JOIN ( SELECT CUSTOMER_ID, MIN(TX_ID) AS TX, SERVICE_DATE FROM ARPB_TRANSACTIONS WHERE VOID_DATE IS NULL -- 提前过滤无效数据,提升效率 GROUP BY CUSTOMER_ID, SERVICE_DATE ) oq ON at.CUSTOMER_ID = oq.CUSTOMER_ID AND at.SERVICE_DATE = oq.SERVICE_DATE -- 新增日期关联 AND at.TX_ID = oq.TX WHERE at.CUSTOMER_ID = '12345' AND at.SERVICE_DATE = '2023-03-06' -- 使用标准日期格式 AND at.SERV_TECH_ID = '1125' AND at.VOID_DATE IS NULL
更简洁的方案(使用窗口函数)
窗口函数ROW_NUMBER()在处理“取每组第一条”的场景更直观,避免子查询关联的复杂性:
SELECT TX_ID, CUSTOMER_ID, SERVICE_DATE, SERV_TECH_ID, POS_ID, LOC_ID, REV_CODE, TOTAL_CHG FROM ( SELECT *, ROW_NUMBER() OVER (PARTITION BY CUSTOMER_ID, SERVICE_DATE ORDER BY TX_ID ASC) AS rn FROM ARPB_TRANSACTIONS WHERE CUSTOMER_ID = '12345' AND SERVICE_DATE = '2023-03-06' AND SERV_TECH_ID = '1125' AND VOID_DATE IS NULL ) t WHERE rn = 1 -- 只取每组的第一行(TX_ID最小的行)
内容的提问来源于stack exchange,提问作者Rob Parker MBA CMPE CPXP
相关产品推荐
相关产品推荐

