SQL Server的自定义排序功能

Posted

技术标签:

【中文标题】SQL Server的自定义排序功能【英文标题】:Custom Sorting Function - of SQL Server 【发布时间】:2009-08-24 13:48:31 【问题描述】:

我在 SQL Server 2005 中有一个列,它将版本号存储为我想要排序的字符串。我一直无法找出如何对这一列进行排序,尽管我猜这将是某种自定义函数或比较算法。

谁能指出我从哪里开始的正确方向?我可能在谷歌上搜索错误的东西。

干杯

三分

【问题讨论】:

它究竟以什么格式存储? 【参考方案1】:

我会使用单独的 int 列(例如,如果您正在跟踪主要 + 次要版本,则使用 MajorCol + MinorCol)并运行类似

order by MajorCol, MinorCol

在我的查询中。

【讨论】:

【参考方案2】:

我会考虑使用持久化计算列,它将字符串处理为 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 非常慢。

【讨论】:

我开始怀疑是否可以将版本信息存储在单独的 int 列中。【参考方案3】:

创建一个 SQL CLR 函数是可行的方法。它们非常快速和强大。这将是快速有效的,因为您不必更改任何现有代码,并且您可以在 SQL 语句中指定您需要的所有信息。

SQL CLR 函数可以接受输入字符串,以及其他指定您想从输入字符串中提取哪条信息的参数。然后,您可以对函数的返回值进行排序。

具体来说,我将创建一个接受三个参数的通用函数:输入字符串、正则表达式和组名。该函数将允许您在 SQL 语句中传递您的数据库字段和带有命名组的正则表达式。

SQL CLR 函数将创建一个正则表达式,根据字符串对其进行测试,并最终返回匹配组的值,如果不匹配或组不匹配(如果组是可选的),则返回 null。理想情况下,您希望将相同的正则表达式传递给每个调用(可能作为@regex 之类的变量),以利用已编译正则表达式的任何 CLR 缓存。最终结果将非常灵活和快速。

可以像这样在模式中内联指定正则表达式选项:“(?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>\d1,3)\.(?<Minor>\d1,3)';

select VersionNumber
from YourTable
order by
Cast(RegexMatchNamedGroup( VersionNumber, @regex, 'Major') as int),
Cast(RegexMatchNamedGroup( VersionNumber, @regex, 'Minor') as int)

【讨论】:

以上是关于SQL Server的自定义排序功能的主要内容,如果未能解决你的问题,请参考以下文章

sql server自定义排序

QTableWidget 中的自定义排序

SQL Server中使用自定义指定顺序排序

asp.net 如何方便,快速的实现,好像excel那样的自定义排序与自定义筛选功能。

pyspark 数据框中的自定义排序

java实现多表的自定义查询。