2009-08-24 13 views
0

SQL Server 2005に、並べ替えたい文字列としてバージョン番号を格納する列があります。私はこの列をソートする方法を見つけることができませんでしたが、私はそれが何らかの種類のカスタム関数またはアルゴリズムの比較であると推測しています。SQL Serverのカスタム並べ替え関数

どこから始めるのが正しい方向に向いていますか?私は間違ったものを捜しているかもしれない。

乾杯

トリス

+1

それはどのような形式正確に格納? – gbn

答えて

2

私は別のint型の列を使用したい(例えばMajorCol + MinorColあなたはマイナー+メジャーバージョンを追跡している場合)、私のクエリで

order by MajorCol, MinorCol 

のようなものを実行します。

1

私はint型または文字列またはネイティブのSQL Serverのソートでソートするための適切な何かに文字列を処理して永続計算列を使用して見てしまう -

'1.1.1.1' -> '001.001.001.001' 
'10.10.10.10' -> '010.010.010.010' 
'1.10.1.10' -> '001.010.001.010' 
すなわち

計算された列を並べ替えて、期待される結果を得ることができます。

また、このような操作をインラインで使用できますが、非常に遅い可能性があります。さらに、スカラーUDFは非常に遅いです。

+0

私は、バージョン情報を別々のint列に格納する方がいいかもしれないと思っています。 –

0

SQL CLR関数を作成する方法があります。彼らは非常に高速で強力です。既存のコードを変更する必要がなく、必要なすべての情報をSQL文で指定できるので、迅速かつ効果的です。

SQL CLR関数は、入力文字列と、入力文字列から抽出する情報を指定するその他のパラメータを受け入れることができます。その後、関数の戻り値をソートすることができます。

具体的には、入力文字列、正規表現、グループ名の3つのパラメータを受け入れる汎用関数を作成します。この関数を使用すると、SQL文の中で名前付きグループを持つデータベースフィールドと正規表現を渡すことができます。

SQL CLR関数は正規表現を作成し、それを文字列に対してテストし、最終的に一致したグループの値を返します。一致しなかった場合、またはグループが一致しなかった場合(グループがオプションの場合)はnullになります。理想的には、コンパイルされた正規表現のCLRキャッシングを利用するために、同じ正規表現を各呼び出し(おそらく@regexなどの変数)に渡したいとします。最終的な結果は非常に柔軟で速くなります。

正規表現オプションは、「(?imnsx-imnsx:subexpression)」のようにパターンにインラインで指定できます。参照:msdn.microsoft.com/en-us/library/yd1hzczs.aspx

、このような関数のコードは次のようになります。

[SqlFunction(IsDeterministic=true,IsPrecise=true,DataAccess=DataAccessKind.None,SystemDataAccess=SystemDataAccessKind.None)] 
public static SqlString RegexMatchNamedGroup(SqlChars input, SqlString pattern, SqlString group_name) 
    { 
     Regex regex = new Regex(pattern.Value); 
     Match match = regex.Match(new string(input.Value)); 
     if (!match.Success) //return null if match failed 
      return SqlString.Null; 
     if (group_name.IsNull) //return entire string if matched when no group name is specified 
      return match.Value; 
     Group group = match.Groups[group_name.Value]; 
     if (group.Success) 
      return group.Value; //return matched group value 
     else 
      return SqlString.Null; //return null if named group was not matched   
    } 

あなたのSQL文をことができ、その後、ソートそうのようなあなたの情報に:

declare @regex nvarchar(2000) = '^(?<Major>\d{1,3})\.(?<Minor>\d{1,3})'; 

select VersionNumber 
from YourTable 
order by 
Cast(RegexMatchNamedGroup(VersionNumber, @regex, 'Major') as int), 
Cast(RegexMatchNamedGroup(VersionNumber, @regex, 'Minor') as int) 
関連する問題