2016-06-13 10 views
1

でソートされた列の値を取得:は私が持っているどのようなSQL Serverの

私はこれらがちょうど10ダミー行列

ID  SerialNo 
1  101 
2  102 
3  103 
4  104 
5  105 
6  116 
7  117 
8  118 
9  119 
10 120 

をしているしています。実際のテーブルには100,000以上の行があります。

私にすべてのサブシリーズ用[のSerialNo]列の開始と終了要素を返すことができます任意の並べ替え技術のような方法または式を:私が取得したいもの

。例えば

期待される結果:101-105、上記の結果では、115-120

コンマ分離は重要ではありません、唯一の開始と終了の要素が重要です。

を私は開始を取得し、テーブルに格納されたばかりの要素を終了していた中でループを実行して、PL/SQLプログラミングでそれをやった:私が試してみました何

。 しかし、いいえ。の行数(100,000以上)の場合、クエリの実行には約2分かかります。

SQL Serverのソート手法についても検索しましたが、何も見つかりませんでした。すべての行をレンダリングするには、ソートアルゴリズムの2倍の時間がかかります。

+0

サブシリーズを定義する範囲はどのくらいですか? – Swapnil

+0

ギャップと島を探してください。 – adrianm

+0

2番目の範囲は115-120で、116-120ではないのはなぜですか? –

答えて

0

declare @t table (ID int not null, SerialNo int not null) 
insert into @t(ID,SerialNo) values 
(1 ,101), (2 ,102), (3 ,103), 
(4 ,104), (5 ,105), (6 ,116), 
(7 ,117), (8 ,118), (9 ,119), 
(10,120) 

;With Starts as (
    select t1.SerialNo,ROW_NUMBER() OVER (ORDER BY t1.SerialNo) as rn 
    from 
     @t t1 
      left join 
     @t t1_no 
      on t1.SerialNo = t1_no.SerialNo + 1 
    where t1_no.ID is null 
), Ends as (
    select t1.SerialNo,ROW_NUMBER() OVER (ORDER BY t1.SerialNo) as rn 
    from 
     @t t1 
      left join 
     @t t1_no 
      on t1.SerialNo = t1_no.SerialNo - 1 
    where t1_no.ID is null 
) 
select 
    s.SerialNo as StartSerial, 
    e.SerialNo as EndSerial 
from 
    Starts s 
     inner join 
    Ends e 
     on s.rn = e.rn 

ロジックStartが電流未満SerialNoつを有するない行が存在しない行であることですEndは、現在の行より1つ多くSerialNoの行が存在しない行です。

SerialNoのインデックスにインデックスがない場合でも、パフォーマンスが低下することがあります。

結果:

StartSerial EndSerial 
----------- ----------- 
101   105 
116   120 

あなたは、特定の結果がどのように見えるかを気にしていないようでしたので、うまくいけば可能です。また、物事をセットベースにしています。

+0

私のために働いて..!ありがとう@damien_the_unbeliever –

1

すべてのサブシリーズに5個のレコードを含めると仮定すると、以下のSQLを使用すると予想されます。私はこれが役立つことを願っています

ちょうど非常に簡単であり、各系列の開始と終了を求める
DECLARE @subSeriesRange INT=5; 

CREATE TABLE #Temp(ID INT,SerialNo INT); 

INSERT INTO #Temp VALUES(1,101), 
(2,102), 
(3,103), 
(4,104), 
(5,105), 
(6,116), 
(7,117), 
(8,115), 
(9,119), 
(10,120); 

SELECT STUFF((SELECT CONCAT(CASE ID%@subSeriesRange WHEN 1 THEN ',' ELSE '-' END,SerialNo) 
     FROM #Temp 
     WHERE ID%@subSeriesRange = 1 OR ID%@subSeriesRange=0 
     ORDER BY ID 
     FOR XML PATH('')),1,1,'' 
     ); 

DROP TABLE #Temp; 
+0

「サブシリーズ」の定義がない場合、あなたの答えは機能します。 – Alex

+0

ここではサブシリーズの範囲は何でも構いません。@Alex thnx –

+0

こんにちは@Priyank、rangeを定義するsubSeriesRange変数を追加しました。 – Swapnil

関連する問題