Sql server 如何获取varchar列中数值的最大值

Sql server 如何获取varchar列中数值的最大值,sql-server,tsql,Sql Server,Tsql,我有一个带有nvarchar列的表。此列具有以下值,例如: 983 294 a343 a3546f 等等 我想取这个值的最大值,但不是文本,而是数字。在这个例子中,数字是: 983 294 343 3546 最大值是最后一个-3546。如何在Microsoft SQL上的TSQL中执行此操作?据我所知,您需要创建一个进程或用户定义的函数来删除列,以便您可以实际将其转换为INT或其他适当的数据类型,然后您可以最大限度地使用它。CAST可能会起作用 SELECT MAX(CAST(yourColum

我有一个带有nvarchar列的表。此列具有以下值,例如:

983 294 a343 a3546f 等等

我想取这个值的最大值,但不是文本,而是数字。在这个例子中,数字是:

983 294 343 3546
最大值是最后一个-3546。如何在Microsoft SQL上的TSQL中执行此操作?

据我所知,您需要创建一个进程或用户定义的函数来删除列,以便您可以实际将其转换为INT或其他适当的数据类型,然后您可以最大限度地使用它。

CAST可能会起作用

SELECT MAX(CAST(yourColumn AS int)) AS maxColumns FROM yourTable
编辑。 我没有读完整的问题,似乎

– Function to strip out non-numeric chars
ALTER FUNCTION dbo.UDF_ParseNumericChars
(
  @string VARCHAR(8000)
)
RETURNS VARCHAR(8000)
AS
BEGIN
  DECLARE @IncorrectCharLoc SMALLINT
  –SET @IncorrectCharLoc = PATINDEX(’%[^0-9A-Za-z]%’, @string)
  SET @IncorrectCharLoc = PATINDEX(’%[^0-9.]%’, @string)
  WHILE @IncorrectCharLoc > 0
  BEGIN
    SET @string = STUFF(@string, @IncorrectCharLoc, 1, ”)
    SET @IncorrectCharLoc = PATINDEX(’%[^0-9.]%’, @string)
  END
  SET @string = @string
  RETURN @string
END
GO

通过使用用户定义的函数将值解析为int,然后运行select,我对reg exp答案进行了表决

SELECT MAX(dbo.parseVarcharToInt(column)) FROM table

首先安装一个正则表达式函数。有可以剪切/粘贴的代码

然后使用该文章中的RegexReplace,您可以从字符串中提取数字:

dbo.RegexReplace( '.*?(\d+).*', myField, '$1' )
然后将此字符串转换为数字:

CAST( dbo.RegexReplace( '.*?(\d+).*', myField, '$1' ) AS INT )

然后在SELECT中的MAX函数中使用此表达式。

您可以编写如下函数

create FUNCTION [dbo].[getFirstNumeric](
    @s VARCHAR(50)
)  
RETURNS int AS 
BEGIN

set @s = substring(@s,patindex('%[0-9]%',@s),len(@s)-patindex('%[0-9]%',@s) + 1) 
if patindex('%[^0-9]%',@s) = 0
    return @s
set @s = substring(@s,1,patindex('%[^0-9]%',@s)-1) 

return cast(@s as int)
end
然后打电话

select max(dbo.getFirstNumeric(yourColumn)) from yourTable

如果您正在使用SQL Server 2005或从未使用过SQL Server 2005,您也可以使用Sung Meister发布的解决方案,您可以尝试在不使用正则表达式的情况下保持其简单性

这是来源

create table #t ( val varchar(100) )
insert #t select 983
insert #t select 294
insert #t select 'a343'
insert #t select 'a3546f';
GO

;with ValueRange as (
    select  val,
        [from] = patindex('%[0-9]%', val), 
        [to] = case patindex('%[a-z]', val) 
            when 0 then len(val) 
            else patindex('%[a-z]', val) - patindex('%[0-9]%', val) 
               end
    from    #t
)
select  substring(val, [from], [to]) as val
from    ValueRange VR
order by cast(substring(val, [from], [to]) as int) desc

正如Jason Cohen所说的,这是一个老问题,我知道-但要为其他人添加知识库

假设所有值中至少有一个数字:

Select max(convert(int, SubString(VarName, PATINDEX('%[0-9]%',VarName), Len(VarName))))
from ATable

这是我的简单答案。你可以试试。但它适用于固定的可移动字符串值

select max(cast(SUBSTRING(T.column,3,len(T.column)) as int)) from tablename T

不,没有外部进程是可能的。没错,我的术语“进程”是误导性的,你的正则表达式示例是一个很棒的解决方案!将varchar值“48a”转换为int数据类型时,转换失败。您最初的查询帮助了我。我有4个字符在前面,我剥去了使用子字符串。干杯。如果使用SQL2005或更高版本,那么我可能会使用用户定义的CLR函数来处理正则表达式,而不是包装OLE对象。虽然安装正则表达式函数可能非常有用,但在这种特殊情况下,没有必要安装正则表达式函数,使用patindex的用户定义函数或CTE将满足1的要求。我的RegexReplace得到5个参数,而不是3个:pattern、replacement、subject、global和multiline 2。我仍然得到'4564a'的'4564a',并且应该有4564,所以它在这个表单中不起作用:3。当我用“$1”替换myField时,我总是只得到我号码的最后一位。@tomaszs-我有一个错误,请参阅上面的新代码。我在第一个.*表达式中为非贪婪累加器添加了一个“?”。这就是为什么只有一个数字。@tomasz只需添加GO或;之前WITH@Sung-我在WITH之前添加了一个分号,我认为如果在SQL 2005中对一批语句使用CTE,则CTE定义之前的语句必须有一个分号。@kristof:你是对的。我从select语句中分别运行了create和insert。当我公布消息来源时,我应该更彻底些我已经更新了源代码。
select max(cast(SUBSTRING(T.column,3,len(T.column)) as int)) from tablename T