2012-02-16 44 views
3

我有一個varchar()字段,名爲identifier,其中包含實體的唯一名稱。如何搜索給定字符串值「周圍」的行?

我想搜索該表並找到具有給定標識符的行,該標識符任一側最多有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個字符。

回答

2

這個答案是有點compilerfriendly

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 
+0

我沒有考慮過UNION,我的頭被困在試圖在一個SELECT內完成。我選擇了這個答案而不是其他類似的答案,因爲它也處理最終結果集的排序。 – richardtallent 2012-02-17 15:11:15

+0

是什麼讓這個更「編譯友好」?我錯過了排序要求,但是我看不出這有什麼不同,「編譯器友好」 - 比我的更好。事實上,除了添加排序要求之外,它可能也是copypasta。 – 2012-02-17 15:37:53

+0

@PittsburghDBA你的腳本不能編譯,我不介意你明白這一點。但是你的腳本是無效的。 – 2012-02-17 18:11:05

5
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 
+0

我首先想到的也是如此。 – 2012-02-16 23:24:41

+0

可能希望在'identifier'上同時具有升序和降序索引。 – HABO 2012-02-17 00:33:09