【问题标题】:How can I search for rows "around" a given string value?如何搜索“围绕”给定字符串值的行?
【发布时间】:2012-02-17 17:26:13
【问题描述】:

我有一个表,其中有一个名为 identifiervarchar() 字段,其中包含实体的唯一名称。

我想搜索表格并找到具有给定标识符的行并且在该标识符的任一侧最多 10 行,按字母顺序排序(即搜索的标识符及其两侧相邻的行)。

在 SQL Server 2005 中表达此问题的最佳方法是什么?我猜有一些 ROW_NUMBER() 魔法可以做到这一点,但我没有找到任何通过查询来做这种事情。

这是我目前所能达到的最接近的结果,但性能糟糕

WITH 
  allrows AS (
   SELECT *, ROW_NUMBER() OVER(ORDER BY identifier DESC) AS RN
       FROM mytable
  ),
  centerrow AS (
    SELECT RN AS CRN FROM allrows WHERE identifier = 'MyValue'
  )
SELECT * FROM allrows, centerrow 
WHERE RN BETWEEN (centerrow.CRN - 10) AND (centerrow.CRN + 10)

该表有超过200万条记录,标识符字段可以长达1000个字符。

【问题讨论】:

    标签: sql-server-2005 tsql


    【解决方案1】:
    SELECT TOP 11 * FROM MyTable WHERE identifier >= 'My Value' ORDER BY identifier ASC
    UNION ALL
    SELECT TOP 10 * FROM MyTable WHERE identifier < 'My Value' ORDER BY identifier DESC
    

    【讨论】:

    • 可能希望在identifier 上有升序和降序索引。
    【解决方案2】:

    这个答案对编译器更友好一点

    declare @e table(identifier varchar(5))
    insert @e values (0),(1),(2),(3),(4)
    
    SELECT * FROM(
    SELECT top 2 * 
    FROM @e WHERE 
    identifier >= '2' 
    ORDER BY identifier asc) a
    UNION ALL 
    SELECT * FROM (
    SELECT top 1 * 
    FROM @e 
    WHERE identifier < '2' 
    ORDER BY identifier desc ) b
    

    【讨论】:

    • 我没有考虑过 UNION,我一直想在单个 SELECT 中实现它。我选择了这个答案而不是另一个类似的答案,因为它还处理最终结果集的排序。
    • 是什么让这更“编译器友好”?我错过了排序要求,但我看不出这与我的“编译器友好”有何不同。其实除了增加排序要求,还不如copypasta。
    • @PittsburghDBA 您的脚本无法编译,我不介意您明白这一点。但是你的脚本是无效的。
    • 哈哈 - 我知道我在那里做了什么;我将 ORDER BY 放在 SELECT 中。我的错。我真的应该在适当的编辑器中输入这些,而不是在答案框中。呜呜。也许下次您可以说“其他解决方案无法编译”。我以为您是在暗示优化而不是实际编译。傻我。
    • @PittsburghDBA 我也在考虑只修复你的 scipt。它几乎就在那里。我投票赞成你,因为你有正确的想法。
    猜你喜欢
    • 2012-01-05
    • 1970-01-01
    • 2018-02-10
    • 2017-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-04
    • 1970-01-01
    相关资源
    最近更新 更多