SQL技术咨询:去重列不排除行及子类别预算聚合问题
我来帮你逐个解决这两个SQL问题:
问题1:如何在SQL中实现查询指定列去重但不排除任何数据行?
你要的应该是保留所有原始数据行,但让指定列的重复值只在首次出现时显示,后续重复行该列可以显示空值或自定义标记,而不是用DISTINCT直接删掉重复行。这种需求用窗口函数就能轻松实现,比如ROW_NUMBER():
举个例子,假设你的表是sales_data,要去重的列是product_category,其他需要展示的列是order_id、sale_amount:
SELECT -- 仅当该类别是组内第一行时显示类别名称,否则显示NULL(也可换成空字符串/自定义标记) CASE WHEN ROW_NUMBER() OVER (PARTITION BY product_category ORDER BY order_id) = 1 THEN product_category ELSE NULL END AS dedup_product_category, order_id, sale_amount FROM sales_data;
这个方法的核心是用PARTITION BY按指定列分组,给每组内的行编号,只保留第一行的列值,其他行做特殊处理,同时所有原始行都被完整保留。
问题2:为销售聚合报表添加预算,处理重复子类别
首先明确你的核心痛点:qb_item_group里存在除唯一ID外完全相同的子类别记录,而灯具类总预算需要是10000——这说明这些重复的子类别属于同一个业务分类,它们的预算需要合并计算(要么是重复子类别预算相加得10000,要么是预算本身相同,我们需要去重后取唯一值)。
我的解决思路是:先对预算表做去重处理,再和你的销售聚合查询关联。
假设你的原销售聚合查询是这样的(按日期范围、类别/子类别聚合销售额):
SELECT category, subcategory, SUM(sale_amount) AS total_sales FROM sales_records WHERE sale_date BETWEEN '2024-01-01' AND '2024-06-30' GROUP BY category, subcategory;
那我们可以用CTE先处理qb_item_group的重复子类别,再关联销售数据:
WITH cleaned_budgets AS ( -- 按类别、子类别分组,合并重复记录的预算 SELECT category, subcategory, SUM(budget_amount) AS total_budget -- 如果重复子类别预算是相同值,也可以用MAX(budget_amount) FROM qb_item_group GROUP BY category, subcategory -- 用除ID外的业务唯一字段分组,去掉ID不同的重复项 ) SELECT s.category, s.subcategory, s.total_sales, -- 若某个类别/子类别无预算,用0填充 COALESCE(cb.total_budget, 0) AS total_budget FROM ( -- 原销售聚合查询 SELECT category, subcategory, SUM(sale_amount) AS total_sales FROM sales_records WHERE sale_date BETWEEN '2024-01-01' AND '2024-06-30' GROUP BY category, subcategory ) s LEFT JOIN cleaned_budgets cb ON s.category = cb.category AND s.subcategory = cb.subcategory;
这样处理后,灯具类下那些ID不同但其他信息一致的子类别会被合并成一行,它们的预算总和(或唯一值)就会是你需要的10000,最终报表里就能同时展示销售额和对应的预算了。
内容的提问来源于stack exchange,提问作者user3308219
相关产品推荐
相关产品推荐

