如何编写SQL获取客户重复下单数据,同产品订单仅保留2条?
解决方案
要实现同一客户同一产品最多保留前2条订单的需求,窗口函数ROW_NUMBER() 是最合适的工具,它能在分组内为每条记录分配序号,再通过筛选序号截断多余数据。以下是调整后的SQL:
SELECT customer_account, customer_name, order_id, suburb, product_id FROM ( SELECT CUSTOMER.customer_account, CUSTOMER.customer_name, CUSTOMER.order_id, DELIVERY.suburb, "ORDER".product_id, -- 按客户账号+产品ID分组,组内按订单ID排序(可根据实际需求调整排序字段) ROW_NUMBER() OVER ( PARTITION BY CUSTOMER.customer_account, "ORDER".product_id ORDER BY CUSTOMER.order_id ASC ) AS row_num FROM CUSTOMER LEFT JOIN DELIVERY ON CUSTOMER.customer_account = DELIVERY.customer_account AND CUSTOMER.order_id = DELIVERY.order_id LEFT JOIN "ORDER" ON CUSTOMER.customer_account = "ORDER".customer_account AND CUSTOMER.order_id = "ORDER".order_id WHERE "ORDER".product_id BETWEEN 5 AND 10 AND SUBSTR(CUSTOMER.customer_name, 1, 1) = 'J' ) filtered WHERE row_num <= 2;
关键说明:
- PARTITION BY:指定分组维度(客户账号+产品ID),确保序号仅在每个客户的同一产品订单内生成。
- ORDER BY:定义组内排序规则,这里用
order_id ASC保证取最早的2条订单,若需最新的2条可改为DESC。 - ROW_NUMBER():为每个分组内的记录分配唯一递增序号(从1开始)。
- 外层筛选:只保留序号≤2的记录,实现截断多余订单的效果。
注意事项:
ORDER是SQL关键字,需根据数据库类型用对应符号包裹:Oracle/PostgreSQL用双引号,SQL Server用方括号,MySQL用反引号,避免语法错误。FETCH FIRST是全局条数限制,无法实现分组内的精准截断,因此窗口函数是更适配需求的方案。
内容的提问来源于stack exchange,提问作者user21989387
相关产品推荐
相关产品推荐

