Sql 选择转换为十进制的最大varchar
我试图从一列中获取最大十进制值,然后将其加1以获取下一个值。但是,列的值是varchar类型的,这意味着我必须进行筛选,以确保它只尝试强制转换它可以转换的值,如“123”,同时避免像“123a”这样的值 到目前为止,我所尝试的是:Sql 选择转换为十进制的最大varchar,sql,sql-server,sql-server-2012,Sql,Sql Server,Sql Server 2012,我试图从一列中获取最大十进制值,然后将其加1以获取下一个值。但是,列的值是varchar类型的,这意味着我必须进行筛选,以确保它只尝试强制转换它可以转换的值,如“123”,同时避免像“123a”这样的值 到目前为止,我所尝试的是: SELECT (CAST(MAX(Id) AS DECIMAL(38,0)) + 1) AS 'New ID' FROM database WHERE Id NOT LIKE '%[^0-9]%' --filters out non-numeric ID valu
SELECT
(CAST(MAX(Id) AS DECIMAL(38,0)) + 1) AS 'New ID'
FROM database
WHERE Id NOT LIKE '%[^0-9]%' --filters out non-numeric ID values
AND (LEN(Id) + 1) < 39 --ensures ID is less than length 39
但是,当我运行此命令时,如果ID列中存在一个值(如9)和一个值(如100),MAX将优先考虑9而不是100
我还尝试:
SELECT
(CAST(MAX(CAST(Id AS DECIMAL(38,0))) AS DECIMAL(38,0)) + 1) AS 'New ID'
FROM database
WHERE Id NOT LIKE '%[^0-9]%'
AND (LEN(Id) + 1) < 39
但是,这会导致将varchar转换为数字时出错,因为我假设它会在筛选WHERE子句中的非数字ID之前尝试将其转换为十进制。我也尝试过在一开始就去掉多余的演员阵容,但仍然有同样的问题
谢谢你的帮助 您应该使用try\u convert:
您的示例将转换回十进制,但我认为您需要一个字符串:
SELECT TRY_CONVERT(VARCHAR(38), MAX(TRY_CONVERT(DECIMAL(38, 0), id)) + 1) AS [New ID]
FROM database
WHERE Id NOT LIKE '%[^0-9]%' AND (LEN(Id) + 1) < 39 ;
您面临的问题取决于SQL Server处理查询的方式。我们打算在SELECT之前处理WHERE子句。但是,计算可能不是这样设置的。因此,SQL Server最终会在转换将被过滤掉的值时执行不必要的工作,但随后会在中断查询时发生错误
在我看来,这是SQLServer实现中的一个错误。人们认为,即使没有选择行,它们也有充分的理由允许错误通过。我们都同意这是一个不便
在尝试转换之前,CASE语句将用于此目的。首先转换为十进制,然后获取最大数值10>9,然后添加1,必要时再转换为字符串
SELECT
CAST(MAX(CAST(Id AS DECIMAL(38,0))) + 1) AS VARCHAR(39)) AS [New ID]
FROM database
WHERE Id NOT LIKE '%[^0-9]%'
AND LEN(Id) < 39;
您缺少的是空字符串。当Id为空字符串时,您的条件“[^0-9]”为true。这应该起作用:
SELECT
(MAX(CAST(Id AS DECIMAL(38,0))) + 1) AS 'New ID'
FROM database
WHERE Id NOT LIKE '%[^0-9]%'
AND Id <> ''
AND (LEN(Id) + 1) < 39
外部强制转换是冗余的MAX将返回与其参数相同的类型
PS:WHERE子句在SELECT子句之前求值,因此如果您过滤掉WHERE中的无效值,SELECT中的转换将不会失败。切换顺序,使转换发生在max.MAXCASTId之前,即小数点38,0+1作为“新ID”或类似的值。。或者使用CTE首先消除非数字ID,然后强制转换以获得最大值+1
SELECT
(MAX(CAST(Id AS DECIMAL(38,0))) + 1) AS 'New ID'
FROM database
WHERE Id NOT LIKE '%[^0-9]%'
AND Id <> ''
AND (LEN(Id) + 1) < 39