You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在SQL Server中按客户分区获取首条无订单记录?

问题描述

我在SQL Server数据库中有以下数据,想要为每个customer_id返回该客户首次无订单(order_count=0)日期对应的row_id;如果客户没有无订单的记录,返回null。

原始数据

row_idcustomer_iddateorder_count
112024-01-012
212024-01-021
312024-01-035
412024-01-040
512024-01-053
622024-01-015
722024-01-023
822024-01-039
922024-01-041
1022024-01-053
1132024-01-010
1232024-01-021
1332024-01-035
1432024-01-040
1532024-01-053

期望结果

customer_idrow_id
14
2null
311

我考虑用按customer_id分区的窗口函数,但不确定具体逻辑,请问对应的SQL语句该怎么写?


解决方案

可以通过窗口函数筛选每个客户最早的无订单记录,再结合LEFT JOIN确保所有客户都被返回,具体SQL如下:

WITH customer_first_zero AS (
    SELECT 
        customer_id,
        row_id,
        -- 按客户分区,给order_count=0的记录按日期升序排序,最早的标记为1
        ROW_NUMBER() OVER (
            PARTITION BY customer_id 
            ORDER BY date ASC
        ) AS rn
    FROM your_table_name
    WHERE order_count = 0
)
SELECT 
    c.customer_id,
    cfz.row_id
FROM (
    -- 获取所有唯一客户ID,确保无无订单记录的客户也能被返回
    SELECT DISTINCT customer_id FROM your_table_name
) c
LEFT JOIN customer_first_zero cfz 
    ON c.customer_id = cfz.customer_id 
    AND cfz.rn = 1; -- 只保留每个客户最早的那条无订单记录

逻辑说明

  1. CTE部分:先筛选出所有order_count=0的记录,用ROW_NUMBER()按客户分区、日期升序排序,这样每个客户的第一条无订单记录会被标记为rn=1。
  2. 主查询:先提取所有唯一的客户ID,再通过LEFT JOIN关联CTE中rn=1的记录,确保没有无订单记录的客户返回null。

如果你的数据库中有独立的客户表(比如customers表),可以直接用该表代替主查询中的SELECT DISTINCT customer_id FROM your_table_name,查询效率会更高:

WITH customer_first_zero AS (
    SELECT 
        customer_id,
        row_id,
        ROW_NUMBER() OVER (
            PARTITION BY customer_id 
            ORDER BY date ASC
        ) AS rn
    FROM your_table_name
    WHERE order_count = 0
)
SELECT 
    c.customer_id,
    cfz.row_id
FROM customers c
LEFT JOIN customer_first_zero cfz 
    ON c.customer_id = cfz.customer_id 
    AND cfz.rn = 1;

内容的提问来源于stack exchange,提问作者mateoc15

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 06:33:12