选择转换为小数的最大 varchar

Posted

技术标签:

【中文标题】选择转换为小数的最大 varchar【英文标题】:Selecting maximum varchar casted into a decimal 【发布时间】:2016-05-10 20:49:43 【问题描述】:

我正在尝试从列中获取最大 Decimal 值,然后将 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 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 之前尝试将其转换为小数。我也试过在开始时去掉多余的演员,但这仍然有同样的问题。

感谢您的帮助!

【问题讨论】:

切换顺序,使转换发生在最大值之前。 MAX(CAST(Id AS DECIMAL(38,0)) + 1) AS 'New ID' 或类似的东西.. 或使用 CTE 首先消除非数字 ID,然后强制转换以获得最大 + 1 【参考方案1】:

您缺少的是空字符串。您的条件:当 Id 为空字符串时,Id NOT LIKE '%[^0-9]%' 为真。这应该有效:

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

外部 CAST 是多余的(MAX 将返回与其参数相同的类型)。

PS:WHERE 子句在 SELECT 子句之前进行求值,所以如果过滤掉 WHERE 中的无效值,SELECT 中的转换不会失败。

【讨论】:

【参考方案2】:

你应该使用try_convert():

SELECT MAX(TRY_CONVERT(DECIMAL(38, 0), id)) + 1 AS [New ID]
FROM database
WHERE Id NOT LIKE '%[^0-9]%' AND (LEN(Id) + 1) < 39 ;  

您的示例转换回小数,但我认为您需要一个字符串:

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 最终会在转换将被过滤掉的值方面做不必要的工作——但随后会发生错误并中断查询。

在我看来,这是 SQL Server 实现中的一个错误。人们假设他们有充分的理由允许错误通过,即使没有选择行。我们都同意这是一种不便。

TRY_CONVERT() 之前,CASE 语句将用于此目的。

【讨论】:

【参考方案3】:

首先转换为十进制,然后获取最大(数字)值(因此 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;

【讨论】:

以上是关于选择转换为小数的最大 varchar的主要内容,如果未能解决你的问题,请参考以下文章

matlab如何把小数转换成分数

excel将小数格式转化为分秒毫秒格式

java中的小数,如何分别输出整数部分和小数部分?

C语言编程 对变量保留两位小数 并进行四舍五入

java中BigDecimal和bigInteger如何转换

使用 VBA 将逗号小数转换为句点小数