我的代码有效,但我不知道为什么

时间:2015-03-04 15:17:15

标签: sql sql-server partition

SELECT *
FROM (
        SELECT TOP 100
        o.[Incident ID], 
        o.[Affected CI], 
        o.Title, 
        o.[Description], 
        d.[DB NAME],
        ROW_NUMBER() OVER(PARTITION BY o.[Incident ID] ORDER BY o.[Incident ID]) rn
        FROM Oracle_Incident_Data.dbo.Oracle_Incidents AS O 
        LEFT JOIN Oracle_Incident_Data.dbo.DB_NAMES_ORA$ AS D 
        ON CONCAT(COALESCE(o.[Affected CI],' '), COALESCE(o.[Title],' '), COALESCE(o.[Description],' ')) LIKE '%' + d.[DB NAME] + '%'
    ) a
WHERE rn = 1

朋友推荐我使用分区修复我之前查询返回匹配的问题,找不到DB Name中的匹配并转移到下一个事件。问题是现在我真的不明白它在做什么,我想调整匹配。接下来我想弄清楚如何使它加入最长匹配字符串,但我需要先了解分区在这个查询中的工作原理。提前谢谢。

1 个答案:

答案 0 :(得分:3)

首先,窗口函数令人困惑。毫无疑问。

ROW_NUMBER() OVER(PARTITION BY o.[Incident ID] ORDER BY o.[Incident ID]) rn

该行将创建一个从1开始的row_number,并为每条记录提升。对于在查询结果集中遇到的每个新1,它将从o.[Incident ID]开始。它也确定了o.[Incident ID]的编号顺序。

例如:

 rn   IncidentID
 1       A
 2       A
 3       A
 1       B
 2       B
 1       C
 2       C
 3       C

要查看它正在做什么,请将子查询单独输出并自行运行,然后按o.[Incident ID]对查询结果进行排序。它会变得清晰。

使用WHERE rn = 1的主查询只过滤掉ROW_NUMBER1的记录。

所有这一切,我都不认为它的写作方式是正确的。 PARTITION BYORDER BY真的不应该是一样的。当您的记录集中有多个记录具有相同的o.[Incident ID]时,它将导致arbritrary编号。每次运行查询时,这些结果都可能会发生变化,具体取决于数据库从基础表中获取数据的方式。

相反,当你按ORDER BY进行分区时,你可能应该o.[Incident ID]实际产生ORDER的东西。通常这是一个DATE或一些测量字段,但它也可能像你的标题或描述一样随意。