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

如何编写有效SQL查询:按DocNum降序取前25个去重customer?

如何编写符合需求的SQL查询

你的需求是按DocNum字段降序排序,获取前25个不重复的customer字段值,但当前给出的查询存在逻辑问题,无法正确实现需求,下面具体分析并给出解决方案:

原查询的问题

原查询语句:

SELECT DISTINCT TOP 25 customer
FROM tt
WHERE DocNum LIKE '%_%' AND UPPER(U_NAME) NOT LIKE '%E G%'
ORDER BY DocNum DESC

这里的核心矛盾:

  • DISTINCT会先对customer去重,但ORDER BY DocNum DESC依赖的是未去重前的记录字段,多数SQL数据库(如SQL Server)会直接报错,因为无法确定每个去重后的customer对应哪个DocNum来排序;
  • 即使部分数据库允许执行,结果也不符合预期——同一个customer可能对应多个DocNum,排序逻辑混乱,无法保证取到的是拥有最大DocNum的前25个客户。

正确的实现方案

根据需求核心,分两种常见场景给出写法:

场景1:取拥有最大DocNum的前25个不同客户

这是最常见的需求逻辑:先找出每个客户最新(最大)的DocNum,再按该值降序排序,取前25个客户。

方法1:窗口函数实现(灵活性高)

SELECT TOP 25 customer
FROM (
    SELECT 
        customer,
        -- 按客户分组,每组内按DocNum降序编号,rn=1对应该客户的最大DocNum记录
        ROW_NUMBER() OVER (PARTITION BY customer ORDER BY DocNum DESC) AS rn
    FROM tt
    WHERE DocNum LIKE '%_%' AND UPPER(U_NAME) NOT LIKE '%E G%'
) AS sub_query
WHERE rn = 1
ORDER BY DocNum DESC;

方法2:GROUP BY聚合实现

SELECT TOP 25 customer
FROM (
    SELECT 
        customer,
        MAX(DocNum) AS max_docnum -- 找出每个客户的最大DocNum
    FROM tt
    WHERE DocNum LIKE '%_%' AND UPPER(U_NAME) NOT LIKE '%E G%'
    GROUP BY customer
) AS sub_query
ORDER BY max_docnum DESC;

场景2:按记录DocNum降序遍历,收集25个不重复customer

如果需求是按记录的DocNum从大到小遍历,遇到新的customer就保留,直到凑够25个不重复值,可使用以下写法:

SELECT DISTINCT TOP 25 customer
FROM (
    SELECT 
        customer,
        -- 按DocNum降序给所有记录排名,相同DocNum的记录排名一致
        DENSE_RANK() OVER (ORDER BY DocNum DESC) AS rank_num
    FROM tt
    WHERE DocNum LIKE '%_%' AND UPPER(U_NAME) NOT LIKE '%E G%'
) AS sub_query
ORDER BY rank_num;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 13:18:07