去重计数如何开窗
时间: 2025-06-12 07:57:43 浏览: 4
### 如何在去重计数时使用开窗函数
在 SQL 查询中,当需要对数据进行去重并统计数量时,可以借助开窗函数完成这一需求。相比传统的 `GROUP BY` 和 `DISTINCT` 方法,开窗函数提供了更灵活的方式处理复杂场景。
#### 去重计数的核心逻辑
通过开窗函数中的 `ROW_NUMBER()` 或者 `RANK()` 来标记每一组内的记录顺序,并基于此筛选出唯一的记录[^2]。具体来说:
- **`ROW_NUMBER()`**: 为每条记录分配一个唯一编号,按指定条件排序后,取第一个作为代表。
- **`PARTITION BY`**: 定义分组依据,类似于 `GROUP BY` 的作用,但保留了原始行数。
- **`ORDER BY`**: 在每个分组内部定义排序规则,决定哪一条记录被选为代表。
最终可以通过 `WHERE` 子句过滤掉多余的重复项,仅保留所需的一条记录用于后续计数操作。
以下是具体的实现方式及其解释:
```sql
WITH RankedData AS (
SELECT
column_to_count, -- 被统计的列
other_columns, -- 可能存在的其他辅助列
ROW_NUMBER() OVER(PARTITION BY key_column ORDER BY sort_column) AS rn
FROM your_table_name
)
SELECT
column_to_count,
COUNT(*) AS count_result
FROM RankedData
WHERE rn = 1
GROUP BY column_to_count;
```
#### 关键点解析
1. **创建中间结果集**
使用 CTE(Common Table Expression),即上面代码中的 `RankedData` 表达式,先给每组数据打上序号标签。这里假设我们希望根据某关键字段 (`key_column`) 进行分组,并按照另一个字段(`sort_column`) 排序来确定优先级[^3]。
2. **去除冗余记录**
当设置好窗口之后,在外部查询里加入条件 `rn = 1` ,这样就只选取各组里的第一条记录,从而实现了初步的去重效果。
3. **执行最后一步聚合运算**
对已经清理过的数据再次运用标准的 `GROUP BY` 结合 `COUNT()` 函数得出目标统计数据[^4]。
这种方法的优势在于它不仅能够有效剔除多余副本,而且还能保持原有表格结构不变的同时引入额外计算维度,非常适合于那些既需展示明细又想附加汇总指标的应用场合。
---
### 示例应用案例
假设有如下员工职位信息表 `titles`:
| emp_no | title |
|--------|-------------|
| 10001 | Engineer |
| 10002 | Manager |
| 10003 | Engineer |
| 10004 | Director |
| 10005 | Engineer |
如果我们想知道除去重复人员之外不同职称的数量分布情况,则可以用下面这段脚本解决这个问题:
```sql
WITH UniqueTitles AS (
SELECT
title,
emp_no,
ROW_NUMBER() OVER(PARTITION BY title ORDER BY emp_no) AS row_num
FROM titles
)
SELECT
title,
COUNT(emp_no) AS unique_emp_count
FROM UniqueTitles
WHERE row_num = 1
GROUP BY title;
```
运行以上语句将会得到类似这样的输出结果:
| title | unique_emp_count |
|------------|------------------|
| Engineer | 1 |
| Manager | 1 |
| Director | 1 |
这意味着尽管有多个工程师任职经历,但在我们的新报表里他们只会算作一个人次而已。
---
阅读全文
相关推荐











