2012-02-16 9 views
3

varchar()フィールドにidentifierと呼ばれるエンティティの一意の名前を含むテーブルがあります。与えられた文字列値の "around"行をどのようにして検索できますか?

私はどちらかに(すなわち、検索対象の識別子とその隣接行アルファベット順に並べ替え、テーブルを検索し、与えられた識別子と行とその識別子のいずれかの側の最大10行を見つけたいのですが側)。

これをSQL Server 2005で策定する最良の方法は何ですか?私はこれを行うことができるいくつかのROW_NUMBER()の魔法があると思っていますが、私はこのようなことをするためのgo-byクエリを見つけることはできません。

これは私がこれまでに得ることができるように近いですが、パフォーマンスはひどいです:

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

この回答は、同様に私が最初に考え

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を考慮していませんでしたが、私の頭は1つのSELECT内でそれをやろうとしていました。私はそれが最終的な結果セットの並べ替えを処理するので、他の同様のものに対してこの答えを選んだ。 – richardtallent

+0

これは "コンパイラに優しい"ものですか?私はソートの要件を逃しましたが、私はこれがどのように「コンパイラに優しい」という言い方をしているのか分かりません。実際には、ソート要件を追加する以外に、それは同様にcopypastaかもしれません。 –

+0

@PittsburghDBAあなたのスクリプトはコンパイルされません、私はあなたがポイントを得るのが気にしません。しかし、あなたのスクリプトはそのままでは無効です。 –

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

もう少しcompilerfriendlyです。 –

+0

'identifier'に昇順と降順の両方のインデックスを付けることができます。 – HABO

関連する問題