如何在Partition By中结合条件实现Count Distinct统计?
解决按分区统计不同值并条件返回的SQL问题
你遇到的核心问题是:窗口函数里直接用COUNT(DISTINCT)在多数数据库中不支持,而原来的语句统计的是符合条件的行数,并非去重后的数量。下面给你几种可行的实现方式:
方法一:子查询/CTE预计算分区去重数(通用兼容所有数据库)
先预先算出每个C分区对应的B不同值数量,再关联原表判断返回:
WITH cte AS ( -- 若要统计C分区下所有B的不同值,去掉WHERE条件;若仅统计A='B'的行里的B不同值,保留WHERE SELECT C, COUNT(DISTINCT B) AS distinct_b_count FROM your_table -- WHERE A = 'B' GROUP BY C ) SELECT t.A, t.B, t.C, CASE WHEN t.A = 'B' THEN COALESCE(cte.distinct_b_count, 0) ELSE 0 END AS D FROM your_table t LEFT JOIN cte ON t.C = cte.C;
方法二:利用DENSE_RANK窗口函数(部分场景适用)
如果你的数据库支持窗口函数,可以用DENSE_RANK间接统计去重数量——它会给每个不同的B值分配连续排名,分区内的最大排名就是去重后的数量:
SELECT A, B, C, CASE WHEN A = 'B' THEN COALESCE(MAX(DENSE_RANK() OVER (PARTITION BY C ORDER BY B)), 0) ELSE 0 END AS D FROM your_table;
若仅需统计A='B'的行里的B不同值,调整排序条件即可:
SELECT A, B, C, CASE WHEN A = 'B' THEN COALESCE(MAX(CASE WHEN A='B' THEN DENSE_RANK() OVER (PARTITION BY C ORDER BY CASE WHEN A='B' THEN B END) END) OVER (PARTITION BY C), 0) ELSE 0 END AS D FROM your_table;
方法三:直接使用COUNT(DISTINCT)窗口函数(仅部分数据库支持)
如果你的数据库支持窗口函数中使用COUNT(DISTINCT)(比如PostgreSQL 9.4+、SQL Server 2022+),可以直接写单行语句:
SELECT A, B, C, CASE WHEN A = 'B' THEN COUNT(DISTINCT B) OVER (PARTITION BY C) ELSE 0 END AS D FROM your_table;
内容的提问来源于stack exchange,提问作者ssubr
相关产品推荐
相关产品推荐

