【问题标题】:My code works but I don't know why我的代码有效,但我不知道为什么
【发布时间】:2015-05-05 15:38:45
【问题描述】:
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 名称中找不到匹配项并转到下一个事件。现在的问题是我真的不明白它在做什么,我想调整匹配。接下来我想弄清楚如何让它加入最长的匹配字符串,但我需要先了解分区在这个查询中是如何工作的。提前谢谢你。

【问题讨论】:

  • 你的语法建议除了mysql之外的其他数据库,可能是sql server
  • 这是 sql server 抱歉,标签错误。

标签: sql sql-server partition


【解决方案1】:

开窗函数起初令人困惑。毫无疑问。

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

该行将创建一个从1 开始并为每条记录升序的row_number。对于在查询结果集中遇到的每个新的o.[Incident ID],它将从1 重新开始。它也通过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] 的记录时,它将导致任意编号。每次运行查询时,这些结果可能会发生变化,具体取决于数据库从基础表中获取数据的方式。

相反,您可能应该ORDER BY 一些当您按o.[Incident ID] 分区时实际上会产生 ORDER 的东西。通常这是一个 DATE 或一些度量字段,但它也可以是任意的,例如您的 Title 或 Description。

【讨论】:

  • 对 ROW_NUMBER() OVER (...) 的非常好的和简单的解释有助于那些特别是当他们有自己的数据的上下文而不是仅仅......这里是一个答案而不是理解上下文.
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-13
  • 2020-09-19
  • 2014-01-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多