SQL*_*oob 54 t-sql substring sql-server-2008-r2 patindex
我在具有可变alpha长度的列中有脏数据.我只想删除任何不是0-9的东西.
我不想运行函数或proc.我有一个类似于在文本之后抓取数值的脚本,它看起来像这样:
Update TableName
set ColumntoUpdate=cast(replace(Columnofdirtydata,'Alpha #','') as int)
where Columnofdirtydata like 'Alpha #%'
And ColumntoUpdate is Null
Run Code Online (Sandbox Code Playgroud)
我认为它会工作得很好,直到我发现我认为只有Alpha#12345789格式的某些数据字段不...
需要剥离的数据示例
AB ABCDE # 123
ABCDE# 123
AB: ABC# 123
Run Code Online (Sandbox Code Playgroud)
我只想要123.确实所有数据字段都具有#之前的数字.
我尝试了substring和PatIndex,但我的语法不正确或者其他东西.任何人对解决这个问题的最佳方法有任何建议吗?
谢谢!
Ken*_*rds 72
请参阅此博客文章,了解从SQL Server中的字符串中提取数字.下面是您的示例中使用字符串的示例:
DECLARE @textval NVARCHAR(30)
SET @textval = 'AB ABCDE # 123'
SELECT LEFT(SUBSTRING(@textval, PATINDEX('%[0-9.-]%', @textval), 8000),
PATINDEX('%[^0-9.-]%', SUBSTRING(@textval, PATINDEX('%[0-9.-]%', @textval), 8000) + 'X') -1)
Run Code Online (Sandbox Code Playgroud)
Mik*_*son 40
stuff(Col, 1, patindex('%[0-9]%', Col)-1, '')
Run Code Online (Sandbox Code Playgroud)
i-o*_*one 21
如果数字之间可能存在某些字符(例如千位分隔符),您可以尝试以下操作:
declare @table table (DirtyCol varchar(100))
insert into @table values
('AB ABCDE # 123')
,('ABCDE# 123')
,('AB: ABC# 123')
,('AB#')
,('AB # 1 000 000')
,('AB # 1`234`567')
,('AB # (9)(876)(543)')
;with tally as (select top (100) N=row_number() over (order by @@spid) from sys.all_columns),
data as (
select DirtyCol, Col
from @table
cross apply (
select (select C + ''
from (select N, substring(DirtyCol, N, 1) C from tally where N<=datalength(DirtyCol)) [1]
where C between '0' and '9'
order by N
for xml path(''))
) p (Col)
where p.Col is not NULL
)
select DirtyCol, cast(Col as int) IntCol
from data
Run Code Online (Sandbox Code Playgroud)
输出是:
DirtyCol IntCol
--------------------- -------
AB ABCDE # 123 123
ABCDE# 123 123
AB: ABC# 123 123
AB # 1 000 000 1000000
AB # 1`234`567 1234567
AB # (9)(876)(543) 9876543
Run Code Online (Sandbox Code Playgroud)
要进行更新,请添加ColToUpdate
以选择data
cte 列表:
;with num as (...),
data as (
select ColToUpdate, /*DirtyCol, */Col
from ...
)
update data
set ColToUpdate = cast(Col as int)
Run Code Online (Sandbox Code Playgroud)
BBa*_*r42 17
这适合我:
CREATE FUNCTION [dbo].[StripNonNumerics]
(
@Temp varchar(255)
)
RETURNS varchar(255)
AS
Begin
Declare @KeepValues as varchar(50)
Set @KeepValues = '%[^0-9]%'
While PatIndex(@KeepValues, @Temp) > 0
Set @Temp = Stuff(@Temp, PatIndex(@KeepValues, @Temp), 1, '')
Return @Temp
End
Run Code Online (Sandbox Code Playgroud)
然后像这样调用函数来查看清理过的东西旁边的原始内容:
SELECT Something, dbo.StripNonNumerics(Something) FROM TableA
Run Code Online (Sandbox Code Playgroud)
Har*_*rry 11
聚会已经很晚了,我发现了以下内容,我认为它工作得非常出色……如果有人还在寻找
SELECT
(SELECT CAST(CAST((
SELECT SUBSTRING(FieldToStrip, Number, 1)
FROM master..spt_values
WHERE Type='p' AND Number <= LEN(FieldToStrip) AND
SUBSTRING(FieldToStrip, Number, 1) LIKE '[0-9]' FOR XML Path(''))
AS xml) AS varchar(MAX)))
FROM
SourceTable
Run Code Online (Sandbox Code Playgroud)
Cle*_*ent 10
如果您的服务器支持TRANSLATE功能,那么这是一个优雅的解决方案(在sql server上,它可以在sql server 2017+和sql azure上使用).
首先,它用@字符替换任何非数字字符.然后,它删除所有@字符.您可能需要添加您知道可能存在于TRANSLATE调用的第二个参数中的其他字符.
select REPLACE(TRANSLATE([Col], 'abcdefghijklmnopqrstuvwxyz+()- ,#+', '@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@'), '@', '')
Run Code Online (Sandbox Code Playgroud)
CREATE FUNCTION FN_RemoveNonNumeric (@Input NVARCHAR(512))
RETURNS NVARCHAR(512)
AS
BEGIN
DECLARE @Trimmed NVARCHAR(512)
SELECT @Trimmed = @Input
WHILE PATINDEX('%[^0-9]%', @Trimmed) > 0
SELECT @Trimmed = REPLACE(@Trimmed, SUBSTRING(@Trimmed, PATINDEX('%[^0-9]%', @Trimmed), 1), '')
RETURN @Trimmed
END
GO
SELECT dbo.FN_RemoveNonNumeric('ABCDE# 123')
Run Code Online (Sandbox Code Playgroud)
用这个:
REPLACE(TRANSLATE(SomeString, REPLACE(TRANSLATE(SomeString, '0123456789', '##########'), '#', ''), REPLICATE('#', LEN(REPLACE(TRANSLATE(SomeString, '0123456789', '##########'), '#', '') + 'x') - 1)), '#', '')
Run Code Online (Sandbox Code Playgroud)
演示:
DROP TABLE IF EXISTS #MyTempTable;
CREATE TABLE #MyTempTable (SomeString VARCHAR(255));
INSERT INTO #MyTempTable
VALUES ('ssss123ssg99d362sdg')
, ('hey 62q&*^(n43')
, (NULL)
, ('')
, ('hi')
, ('123');
SELECT SomeString
, REPLACE(TRANSLATE(SomeString, REPLACE(TRANSLATE(SomeString, '0123456789', '##########'), '#', ''), REPLICATE('#', LEN(REPLACE(TRANSLATE(SomeString, '0123456789', '##########'), '#', '') + 'x') - 1)), '#', '')
FROM #MyTempTable;
DROP TABLE IF EXISTS #MyTempTable;
Run Code Online (Sandbox Code Playgroud)
结果:
一些字符串 | (无列名) |
---|---|
ssss123ssg99d362sdg | 12399362 |
嘿62q&*^(n43 | 6243 |
无效的 | 无效的 |
你好 | |
123 | 123 |