SQL Server中按名称与提交日期筛选重复记录的查询确认
需求说明
需要在SQL Server的Document表中筛选出**DocumentName与SubmitDateTime均相同**的重复记录,同时排除已存在于Staging表中的记录。例如仅保留DocumentName为'SampleOne'且SubmitDateTime为'2016-10-14 12:44:39.460'的重复行,排除不匹配的数据。
最初的查询(返回多余数据)
SELECT TOP (13) a.DocumentName, a.SubmitDateTime FROM Document AS a INNER JOIN (SELECT DocumentName, SubmitDateTime, COUNT(*) AS DocCount FROM Document GROUP BY DocumentName, SubmitDateTime HAVING (COUNT(*) > 1)) AS dt ON a.DocumentName = dt.DocumentName AND a.SubmitDateTime = dt.SubmitDateTime LEFT OUTER JOIN Staging b ON a.DocumentId = b.DocumentId WHERE b.DocumentId IS NULL AND a.SubmitDateTime IS NOT NULL AND a.InsertDateTime IS NOT NULL ORDER BY a.SubmitDateTime
待确认的窗口函数查询
改用以下含窗口函数的查询后得到了预期结果,现需确认该查询是否正确:
SELECT t.* FROM ( SELECT s.* , COUNT(*) OVER (PARTITION BY s.DocumentName, s.SubmitDateTime, s.DocumentType) AS DocCount FROM Document s LEFT OUTER JOIN Staging b ON s.DocumentId = b.DocumentId WHERE b.DocumentId IS NULL AND s.SubmitDateTime IS NOT NULL AND s.InsertDateTime IS NOT NULL AND s.DocumentName IS NOT NULL ) t WHERE t.DocCount > 1 ORDER BY t.DocumentName, t.SubmitDateTime
示例数据
| DocumentName | SubmitDateTime |
|---|---|
| SampleOne | 2016-10-14 12:44:39.460 |
| SampleOne | 2016-10-14 12:44:39.460 |
| SampleTwo | 2016-10-14 12:44:39.460 |
| SampleTwo | 2016-10-14 12:44:39.460 |
| SampleThree | 2016-10-14 12:45:32.813 |
| SampleFive | 2016-10-14 12:46:23.423 |
| Doc Name | 2016-10-17 15:15:05.523 |
| Doc Name 2 | 2016-10-17 15:15:32.170 |
| Doc Name | 2016-10-17 15:17:32.153 |
| Doc Name | 2016-10-17 15:17:53.963 |
| Doc Name | 2016-10-17 15:18:15.977 |
| Document Text | 2016-10-17 15:19:22.950 |
| Document Text | 2016-10-17 15:22:25.463 |
查询正确性分析
核心逻辑匹配需求:
- 通过
LEFT JOIN Staging b ON s.DocumentId = b.DocumentId+b.DocumentId IS NULL,正确排除了已存在于Staging表的记录; - 过滤条件
s.SubmitDateTime IS NOT NULL、s.InsertDateTime IS NOT NULL、s.DocumentName IS NOT NULL,避免了无效空值数据干扰; - 窗口函数
COUNT(*) OVER (PARTITION BY ...)用于统计分组内的记录数,最终筛选出计数>1的重复行,符合重复记录的筛选逻辑。
- 通过
需要注意的细节:
原需求仅按DocumentName和SubmitDateTime两个字段判定重复,但当前查询的PARTITION BY额外包含了DocumentType字段。这意味着只有当三个字段完全相同时才会被算作重复记录:- 如果你的实际需求确实需要将
DocumentType纳入重复判定标准,那么这个查询是正确的; - 如果仅需按前两个字段判定重复,需要将
PARTITION BY中的s.DocumentType移除,修改为:COUNT(*) OVER (PARTITION BY s.DocumentName, s.SubmitDateTime) AS DocCount
- 如果你的实际需求确实需要将
内容的提问来源于stack exchange,提问作者Alex Aniapam
相关产品推荐
相关产品推荐

