首页 > 解决方案 > 如何从 sql 中包含“ABCDE $1,000 $1,00,000”的列中删除 $1,000

问题描述

我在 SQL 表中有一个值为“ABCDE $1,000 $1,00,000”的列。我必须删除 1,000 美元,预期结果是“ABCDE 1,00,000 美元”。我如何实现这一目标?这是一个例子。但是,可能存在具有不同数字的数据,我需要从此类列值中识别出较大的数字或较小的数字并将其删除。

SQL Server 并尝试了以下函数来提取数字:

DECLARE @string varchar(100),

 @start int,

 @end int,

 @len int

SET @string = 'ABCDE $1,000 $1,000,000'
set @string = replace(@string, ' ' , '')

set @len = len(@string)

set @start =  PATINDEX('%[0-9]%',@string)

set @end =  PATINDEX('%[^0-9]%',substring(@string, @start, @len))-1

print substring(@string, @start, @end) 

declare
@strAlphaNumeric VARCHAR(256) = 'ABCDE $1,000 $1,000,000'

BEGIN  
DECLARE @intAlpha INT  
SET @intAlpha = PATINDEX('%[^0-9]%', @strAlphaNumeric)  
select @intAlpha
BEGIN  
WHILE @intAlpha > 0  
BEGIN  
SET @strAlphaNumeric = STUFF(@strAlphaNumeric, @intAlpha, 1, '' ) 
--select @strAlphaNumeric  
SET @intAlpha = PATINDEX('%[^0-9]%', @strAlphaNumeric )  
--select @intAlpha
END  
END  
select @strAlphaNumeric
END  
GO  

还尝试了以下功能,看看我是否可以更改为实现此目的的功能:

DECLARE @instr   varchar(max)
SET @instr = 'ABCDE $1,000 $1,000,000'
    DECLARE @workstr  varchar(max) = REPLACE(LTRIM(LTRIM(RTRIM(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
              LTRIM(RTRIM(REPLACE(LTRIM(@instr), ' ', '_'))), CHAR(9), ' '), CHAR(10), ' '), CHAR(11), ' '), CHAR(12), ' '), CHAR(13), ' ')))), ' ', '_'),
    @tokenque VARCHAR(MAX),
    @newstr   INT = 0,
    @token varchar(max),
    @flag_break INT = 0
    print @workstr
-- removes the extra "spaces"
    WHILE CHARINDEX('__', @workstr) <> 0
        BEGIN
        SET @workstr = REPLACE(@workstr, '__' , '_')
        END
    SET @tokenque = @workstr
    WHILE (CHARINDEX('_', @tokenque) <> 0)
    BEGIN
    SET @token = SUBSTRING(@tokenque, 1, CHARINDEX('_', @Tokenque) - 1 )
    IF @token <> '''' -- (') delimiter skipped
      BEGIN
      WHILE CHARINDEX(@token + '_' +  @token, @workstr) <> 0
        BEGIN
        SET @workstr = REPLACE(@workstr, @token + '_' + @token, @token)
        END
      SET @tokenque = SUBSTRING(@tokenque, LEN(@token) + 2, LEN(@tokenque) )
       END
    ELSE SET @tokenque = SUBSTRING(@tokenque, LEN(@token) + 2, LEN(@tokenque) )

    --PRINT @tokenque --if you want to see the progression  
    END
PRINT REPLACE(@workstr, '_', ' ')


标签: sql-servertsql

解决方案


使用这些由文本和数字组成的复合列的想法真的很糟糕,但如果你被这个可怕的任务甩了,那么以下内容可能对你有用:

CREATE FUNCTION getmax(@txt nvarchar(1000)) returns nvarchar(max)
BEGIN
DECLARE @ret nvarchar(max);
WITH t1 AS (
  SELECT Split.b.value('.', 'NVARCHAR(MAX)') da
  FROM ( SELECT CAST('<X>'+REPLACE(@txt, ' ', '</X><X>')+'</X>' AS XML) AS String ) AS a
  CROSS APPLY String.nodes('/X') AS Split(b)
), t2 AS (
  SELECT (SELECT MAX(da) n FROM t1) nam, da, REPLACE(REPLACE(da,'$',''),',','')-0 val
  FROM t1 WHERE LEFT(da,1)='$')
SELECT TOP 1 @ret=nam+' '+da FROM t2 ORDER BY val desc;
RETURN @ret
END

我使用 SQL-Server 的 XML 功能将列拆分为各个部分(首先是文本部分,然后是任意数量的 $-amounts)。然后,我通过删除任何符号和空格来清理 $-amounts,$并按其数值对其进行排序(降序)。之后,我获取第一条记录并将文本部分与原始 $-value 字符串组合,并在首先将其存储在变量中后将其返回@ret

然后,在我的 SQL 服务器上,我遇到了一条错误消息,告诉我,我需要使用设置SET ARITHABORT ON;,之后它才起作用,但到目前为止,我还没有设法让它在整个表上工作。由于某种原因,该函数仅返回第一条记录。


推荐阅读