我有一个包含120列的实验室测试表,所有列都有数据类型varchar
(应该是FLOAT
),但这些列还包含^,*,A-Z,a-z
,逗号,满句子等字符停 ”。”在末尾。我使用以下函数来保存所有数值,包括“。”。
问题是这个.
(点),如果我使用@KeepValues as varchar(50) = '%[^0-9]%'
那么它会删除所有点(例如1.05*L
成为105
)这不是我的东西想。
请你帮我解决这个问题非常有帮助,或者任何其他解决办法都很棒
Create Function [dbo].[RAC]
(@Temp VarChar(1000))
Returns VarChar(1000)
AS
Begin
Declare @KeepValues as varchar(50) = '%[^0-9.]%'
While PatIndex(@KeepValues, @Temp) > 0
Set @Temp = Stuff(@Temp, PatIndex(@KeepValues, @Temp), 1, '')
Return @Temp
End
我的T-SQL CASE
声明是:
,CASE WHEN LTRIM(RTRIM(DBO.RAC([INR]))) NOT IN ('','.')
THEN round(AVG(NULLIF(CAST(DBO.RAC([INR]) as FLOAT), 0)), 2)
END AS [INR]
答案 0 :(得分:3)
由于您拥有SQL2012,因此您可以利用TRY_CONVERT()函数
CREATE FUNCTION [dbo].[RAC] (@input varchar(max))
RETURNS TABLE AS
RETURN (
WITH number_list AS (SELECT ROW_NUMBER() OVER(ORDER BY (SELECT 1)) i FROM sys.objects a)
SELECT TOP 1 TRY_CONVERT(float,LEFT(@input,i)) float_conversion
FROM number_list
WHERE i <= LEN(@input) AND TRY_CONVERT(float,LEFT(@input,i)) IS NOT NULL
ORDER BY i DESC
)
GO
如果您有一个非常有用的实际number_list,请改用它。
DECLARE @table TABLE (data varchar(max))
INSERT @table VALUES
('123.124'),
('123.567 blah.'),
('123.567E10 blah.'),
('blah 45.2')
SELECT *
FROM @table
OUTER APPLY [dbo].[RAC](data) t
答案 1 :(得分:3)
你需要一个基本的正则表达式,它允许你获得两组数字之间只有一个小数的数字(或者可能是完全没有小数的数字)。这需要将SQLCLR用于RegEx功能。您可以找到许多这样的示例,或者您可以使用免费提供的SQLCLR库SQL# (SQLsharp)(我是其作者,但回答此问题所需的功能在免费版本中)。
DECLARE @Expression NVARCHAR(100) = N'\d+(\.\d+)?(e[-+]?\d+)?';
SELECT
SQL#.RegEx_MatchSimple(N'This is a test. Number here 1.05*L.',
@Expression, 1, 'IgnoreCase') AS [TheNumber],
CONVERT(FLOAT, SQL#.RegEx_MatchSimple(N'This is a test. Number here 1.05*L.',
@Expression, 1, 'IgnoreCase')) AS [Float],
CONVERT(FLOAT, SQL#.RegEx_MatchSimple(N'Another test. New number 1.05e4*L.',
@Expression, 1, 'IgnoreCase')) AS [Float2],
CONVERT(FLOAT, SQL#.RegEx_MatchSimple(N'One more test. Yup 1.05e-4*L.',
@Expression, 1, 'IgnoreCase')) AS [Float3]
/*
Returns:
TheNumber Float Float2 Float3
1.05 1.05 10500 0.000105
*/
模式的唯一问题是如果文本中有另一个数字(你确实说有完整的句子),那么你想要的那个。如果您100%确定所需的值始终具有小数,则可以使用更简单的表达式,如下所示:
\d+\.\d+(e[-+]?\d+)?
正则表达式允许使用可选的(e / e + / e-)表示法。
答案 2 :(得分:2)
PATINDEX支持模式匹配,但仅适用于T-SQL模式,并且获取模式以执行所需操作可能是不可能的。 听起来你需要使用正则表达式,你需要一个CLR用户定义的函数,或者你可以通过编写一个应用程序使用SQL Server的外部来实现它。
this question的明确答案将帮助您获得所需内容。
以下是代码的副本,以便于参考:
using System;
using System.Data;
using System.Text.RegularExpressions;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
public partial class UserDefinedFunctions
{
[Microsoft.SqlServer.Server.SqlFunction]
public static SqlString StripNonNumeric(SqlString input)
{
Regex regEx = new Regex(@"\D");
return regEx.Replace(input.Value, "");
}
};