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

如何实现按指定列去重并带条件筛选图书数据的SQL查询?

解决图书数据按指定规则去重的SQL方案

嘿,我来帮你搞定这个图书数据的去重筛选问题!先理清楚你的核心需求:对于同一BookRef+BookFloor+BookSection+OrderType的分组,如果分组里有Orders不为空的行,就只保留这些非空行;如果分组里所有行的Orders都是空的,就只留其中一行。你的HAVING尝试没成功,主要是因为分组逻辑和筛选条件没匹配上需求,咱们换用窗口函数来实现会更灵活。

正确的SQL实现

这里用CTE结合窗口函数来完成筛选,逻辑清晰且符合需求:

WITH ranked_books AS (
    SELECT 
        BookRef, BookFloor, BookSection, Orders, OrderType,
        -- 标记当前分组(BookRef+BookFloor+BookSection+OrderType)是否存在非空Orders的行
        MAX(CASE WHEN Orders IS NOT NULL THEN 1 ELSE 0 END) 
            OVER (PARTITION BY BookRef, BookFloor, BookSection, OrderType) AS has_non_null_orders,
        -- 给分组内的行排序:非空Orders的行优先,空值行按任意顺序编号
        ROW_NUMBER() 
            OVER (PARTITION BY BookRef, BookFloor, BookSection, OrderType 
                  ORDER BY CASE WHEN Orders IS NOT NULL THEN 0 ELSE 1 END) AS rn
    FROM #myTempTable
)
SELECT 
    BookRef, BookFloor, BookSection, Orders, OrderType
FROM ranked_books
WHERE 
    -- 分组有非空Orders时,只保留非空行
    (has_non_null_orders = 1 AND Orders IS NOT NULL)
    -- 分组全是空Orders时,只保留第一行
    OR (has_non_null_orders = 0 AND rn = 1);

代码逻辑解释

  1. CTE部分:
    • has_non_null_orders:通过窗口函数MAX统计当前分组内是否存在Orders非空的行,1表示有,0表示没有。
    • rn:用ROW_NUMBER给分组内的行编号,把Orders非空的行排在最前面(CASE语句将非空值设为0,空值设为1,排序时0在前),空值行的编号从2开始。
  2. 筛选条件:
    • 如果分组存在非空Orders,就只保留那些Orders非空的行(对应你期望输出里OrderType=2的那一行)。
    • 如果分组全是空Orders,就只保留编号为1的那一行(也就是分组里的任意一行,比如OrderType=1、OrderType=3的行)。

为什么你的HAVING语句没生效?

你的原查询把Orders也加入了GROUP BY,这会把同一OrderType下的空Orders和非空Orders分成不同的分组,完全偏离了“同一OrderType下筛选行”的需求;同时HAVING的条件逻辑也没有区分“是否存在非空Orders”的两种场景,所以没法得到正确的结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:21:03