示例输入:
“你好,你好吗”
“纽约市排名第一的披萨店是什么?”
“Dominoes is number 1”
“Blah blah 123123”
“更多blah 12321 123123 123132”
预期产出:
“你好,你好吗”
“纽约市排名第一的披萨店是什么?”
“Dominoes is number”
“Blah blah”
“更多等等”
我认为这是一个两步过程:
我应该得到理想的结果。
我可以想到一些快速而肮脏的方法,但这需要执行得相当好,因为它是一个在繁忙的桌子上运行的触发器,所以我想把它扔给T-SQL专业人员。
有什么建议吗?
答案 0 :(得分:4)
这个解决方案应该更有效率,因为它首先检查字符串是否包含数字,然后检查字符串是否以数字结尾。
CREATE FUNCTION dbo.trim_ending_numbers(@columnvalue AS VARCHAR(100)) RETURNS VARCHAR(100)
BEGIN
--This will make the query more efficient by first checking to see if it contains any numbers at all
IF @columnvalue NOT LIKE '%[0-9]%'
RETURN @columnvalue
DECLARE @counter INT
SET @counter = LEN(@columnvalue)
IF ISNUMERIC(SUBSTRING(@columnvalue,@counter,1)) = 0
RETURN @columnvalue
WHILE ISNUMERIC(SUBSTRING(@columnvalue,@counter,1)) = 1 OR SUBSTRING(@columnvalue,@counter,1) = ' '
BEGIN
SET @counter = @counter -1
IF @counter < 0
BREAK
END
SET @columnvalue = SUBSTRING(@columnvalue,0,@counter+1)
RETURN @columnvalue
END
如果你跑
SELECT dbo.trim_ending_numbers('More blah 12321 123123 123132')
它会返回
'More blah'
答案 1 :(得分:3)
繁忙桌子上的循环不太可能充分发挥作用。使用REVERSE和PATINDEX查找第一个非数字,在那里开始SUBSTRING,然后REVERSE结果。没有循环会很慢。
您的示例意味着您也不想匹配空格。
DECLARE @t TABLE (s NVARCHAR(500))
INSERT INTO @t (s)
VALUES
('Hi there how are you'),('What is the #1 pizza place in NYC?'),('Dominoes is number 1'),('Blah blah 123123'),('More blah 12321 123123 123132')
select s
, reverse(s) as beginning
, patindex('%[^0-9 ]%',reverse(s)) as progress
, substring(reverse(s),patindex('%[^0-9 ]%',reverse(s)), 1+len(s)-patindex('%[^0-9 ]%',reverse(s))) as [more progress]
, reverse(substring(reverse(s),patindex('%[^0-9 ]%',reverse(s)), 1+len(s)-patindex('%[^0-9 ]%',reverse(s)))) as SOLUTION
from @t
最终答案: reverse(substring(reverse(@s),patindex('%[^ 0-9]%',reverse(@s)),1 + len(@s) - patindex('%[^ 0-9]%' ,反向(@s))))
答案 2 :(得分:3)
我相信以下查询快速有用
select reverse(substring(reverse(colA),PATINDEX('%[0-9][a-z]%',reverse(colA))+1,
len(colA)-PATINDEX('%[0-9][a-z]%',reverse(colA))))
from TBLA
答案 3 :(得分:0)
--DECLARE @String VARCHAR(100) = 'the fat cat sat on the mat'
--DECLARE @String VARCHAR(100) = 'the fat cat 2 sat33 on4 the mat'
--DECLARE @String VARCHAR(100) = 'the fat cat sat on the mat1'
--DECLARE @String VARCHAR(100) = '2121'
DECLARE @String VARCHAR(100) = 'the fat cat 2 2 2 2 sat on the mat2121'
DECLARE @Answer NVARCHAR(MAX),
@Index INTEGER = LEN(@String),
@Character CHAR,
@IncorrectCharacterIndex SMALLINT
-- Start from the end, going to the front.
WHILE @Index > 0 BEGIN
-- Get each character, starting from the end
SET @Character = SUBSTRING(@String, @Index, 1)
-- Regex check.
SET @IncorrectCharacterIndex = PATINDEX('%[A-Za-z-]%', @Character)
-- Is there a match? We're lucky here because it will either match on index 1 or not (index 0)
IF (@IncorrectCharacterIndex != 0)
BEGIN
-- We have a legit character.
SET @Answer = SUBSTRING(@String, 0, @Index + 1)
SET @Index = 0
END
ELSE
SET @Index = @Index - 1 -- No match, lets go back one index slot.
END
PRINT LTRIM(RTRIM(@Answer))
注意:我在有效的正则表达式匹配中包含了一个短划线。
答案 4 :(得分:-1)
感谢所有非常有帮助的贡献。进一步提取JUST尾随数字:
, substring(s, 2 + len(s) - patindex('%[^0-9 ]%',reverse(s)), 99) as numeric_suffix
我需要对数字后缀进行排序,因此必须将模式限制为数字并绕过数字的不同长度排序为文本(即我希望2在19之前排序)投射结果:
,cast(substring(s, 2 + len(s) - patindex('%[^0-9]%',reverse(s)),99) as integer) as numeric_suffix