假设我有这样的数据:
string 1: 003Preliminary Examination Plan
string 2: Coordination005
string 3: Balance1000sheet
Run Code Online (Sandbox Code Playgroud)
我期望的输出是
string 1: 003
string 2: 005
string 3: 1000
Run Code Online (Sandbox Code Playgroud)
我想在sql中实现它.请帮忙.提前致谢 :)
Luv*_*Luv 95
首先创造这个 UDF
CREATE FUNCTION dbo.udf_GetNumeric
(
@strAlphaNumeric VARCHAR(256)
)
RETURNS VARCHAR(256)
AS
BEGIN
DECLARE @intAlpha INT
SET @intAlpha = PATINDEX('%[^0-9]%', @strAlphaNumeric)
BEGIN
WHILE @intAlpha > 0
BEGIN
SET @strAlphaNumeric = STUFF(@strAlphaNumeric, @intAlpha, 1, '' )
SET @intAlpha = PATINDEX('%[^0-9]%', @strAlphaNumeric )
END
END
RETURN ISNULL(@strAlphaNumeric,0)
END
GO
Run Code Online (Sandbox Code Playgroud)
现在使用function
as
SELECT dbo.udf_GetNumeric(column_name)
from table_name
Run Code Online (Sandbox Code Playgroud)
我希望这能解决你的问题.
Dev*_*art 36
试试这个 -
查询:
DECLARE @temp TABLE
(
string NVARCHAR(50)
)
INSERT INTO @temp (string)
VALUES
('003Preliminary Examination Plan'),
('Coordination005'),
('Balance1000sheet')
SELECT LEFT(subsrt, PATINDEX('%[^0-9]%', subsrt + 't') - 1)
FROM (
SELECT subsrt = SUBSTRING(string, pos, LEN(string))
FROM (
SELECT string, pos = PATINDEX('%[0-9]%', string)
FROM @temp
) d
) t
Run Code Online (Sandbox Code Playgroud)
输出:
----------
003
005
1000
Run Code Online (Sandbox Code Playgroud)
小智 13
查询:
DECLARE @temp TABLE
(
string NVARCHAR(50)
)
INSERT INTO @temp (string)
VALUES
('003Preliminary Examination Plan'),
('Coordination005'),
('Balance1000sheet')
SELECT SUBSTRING(string, PATINDEX('%[0-9]%', string), PATINDEX('%[0-9][^0-9]%', string + 't') - PATINDEX('%[0-9]%',
string) + 1) AS Number
FROM @temp
Run Code Online (Sandbox Code Playgroud)
Sim*_*mon 11
我发现这种方法的效果比投票最高的答案快大约 3 倍。创建以下函数 dbo.GetNumbers:
CREATE FUNCTION dbo.GetNumbers(@String VARCHAR(8000))
RETURNS VARCHAR(8000)
AS
BEGIN;
WITH
Numbers
AS (
--Step 1.
--Get a column of numbers to represent
--every character position in the @String.
SELECT 1 AS Number
UNION ALL
SELECT Number + 1
FROM Numbers
WHERE Number < LEN(@String)
)
,Characters
AS (
SELECT Character
FROM Numbers
CROSS APPLY (
--Step 2.
--Use the column of numbers generated above
--to tell substring which character to extract.
SELECT SUBSTRING(@String, Number, 1) AS Character
) AS c
)
--Step 3.
--Pattern match to return only numbers from the CTE
--and use STRING_AGG to rebuild it into a single string.
SELECT @String = STRING_AGG(Character,'')
FROM Characters
WHERE Character LIKE '[0-9]'
--allows going past the default maximum of 100 loops in the CTE
OPTION (MAXRECURSION 8000)
RETURN @String
END
GO
Run Code Online (Sandbox Code Playgroud)
测试
测试目的:
SELECT dbo.GetNumbers(InputString) AS Numbers
FROM ( VALUES
('003Preliminary Examination Plan') --output: 003
,('Coordination005') --output: 005
,('Balance1000sheet') --output: 1000
,('(111) 222-3333') --output: 1112223333
,('1.38hello@f00.b4r#\-6') --output: 1380046
) testData(InputString)
Run Code Online (Sandbox Code Playgroud)
性能测试:开始设置测试数据......
--Add table to hold test data
CREATE TABLE dbo.NumTest (String VARCHAR(8000))
--Make an 8000 character string with mix of numbers and letters
DECLARE @Num VARCHAR(8000) = REPLICATE('12tf56se',800)
--Add this to the test table 500 times
DECLARE @n INT = 0
WHILE @n < 500
BEGIN
INSERT INTO dbo.NumTest VALUES (@Num)
SET @n = @n +1
END
Run Code Online (Sandbox Code Playgroud)
现在测试 dbo.GetNumbers 函数:
SELECT dbo.GetNumbers(NumTest.String) AS Numbers
FROM dbo.NumTest -- Time to complete: 1 min 7s
Run Code Online (Sandbox Code Playgroud)
然后根据相同数据的投票最高的答案测试 UDF 。
SELECT dbo.udf_GetNumeric(NumTest.String)
FROM dbo.NumTest -- Time to complete: 3 mins 12s
Run Code Online (Sandbox Code Playgroud)
小数点
如果您需要它来处理小数,您可以使用以下任一方法,我发现它们之间没有明显的性能差异。
'[0-9]'
'[0-9.]'
Character LIKE '[0-9]'
为ISNUMERIC(Character) = 1
(SQL 将单个小数点视为“数字”)奖金
WHERE Character LIKE '[0-9]'
您可以通过替换以下选项轻松适应不同的要求:
WHERE Letter LIKE '[a-zA-Z]' --Get only letters
WHERE Letter LIKE '[0-9a-zA-Z]' --Remove non-alphanumeric
WHERE Letter LIKE '[^0-9a-zA-Z]' --Get only non-alphanumeric
Tec*_*hDo 10
请试试:
declare @var nvarchar(max)='Balance1000sheet'
SELECT LEFT(Val,PATINDEX('%[^0-9]%', Val+'a')-1) from(
SELECT SUBSTRING(@var, PATINDEX('%[0-9]%', @var), LEN(@var)) Val
)x
Run Code Online (Sandbox Code Playgroud)
可以在单行中仅从字符串中获取数字。尝试这个 :
SUBSTRING('your-string-here', PATINDEX('%[0-9]%', 'your-string-here'), LEN('your-string-here'))
Run Code Online (Sandbox Code Playgroud)
注意:仅适用于字符串中的第一个 int,例如:abc123vfg34 返回 123。
小智 7
适用于 SQL Server 2017 及更高版本的解决方案,使用TRANSLATE
:
DECLARE @T table (string varchar(50) NOT NULL);
INSERT @T
(string)
VALUES
('003Preliminary Examination Plan'),
('Coordination005'),
('Balance1000sheet');
SELECT
result =
REPLACE(
TRANSLATE(
T.string COLLATE Latin1_General_CI_AI,
'abcdefghijklmnopqrstuvwxyz',
SPACE(26)),
SPACE(1),
SPACE(0))
FROM @T AS T;
Run Code Online (Sandbox Code Playgroud)
输出:
结果 |
---|
003 |
005 |
1000 |
该代码的工作原理是:
提供的字符串TRANSLATE
可以扩展以包含其他字符。
归档时间: |
|
查看次数: |
223320 次 |
最近记录: |