【问题标题】:Extract largest number from a string in T-SQL从 T-SQL 中的字符串中提取最大数
【发布时间】:2015-06-21 14:11:00
【问题描述】:

我正在使用从 excel 文件中导入的数据进行导入。有一列带有可以包含多个数字的字符串。我正在尝试提取字符串中的最大数字,如果没有字符串,则为 0。 字符串的格式类似于: “100% 消费后再生纸、50% 消费后再生封面、90% 消费后再生电线。” “纸张包含 30% 的消费后内容。” 有时是空字符串或 null。

鉴于字符串的不规则格式,我遇到了问题,我们将不胜感激。

【问题讨论】:

  • 在导入之前不能在 excel 中执行此操作吗?
  • 没有足够的信息来发布答案。

标签: sql sql-server tsql string-matching extraction


【解决方案1】:

我最终创建了一个处理它的函数。代码如下:

CREATE FUNCTION [dbo].[cal_GetMaxPercentFromString] 

RETURNS float
AS
BEGIN
    declare @Numbers Table(number float)
    insert into @Numbers
    Select 0

    declare @temp as varchar(2000) = @string
    declare @position int, @length int, @offset int

    WHILE CHARINDEX('%', @temp) > 0
    BEGIN
        set @position = CHARINDEX('%', @temp)
        set @offset = 1
        set @length = -1
        WHILE @position - @offset > 0 and @length < 0
        BEGIN
            if SUBSTRING(@temp, @position - @offset, 1) not LIKE '[0-9]'
                set @length = @offset - 1    
            set @offset = @offset + 1
        END

        if @length > 0
        BEGIN
            insert into @Numbers
            select CAST(SUBSTRING(@temp, @position - @length, @length) as float)            
        END
        set @temp = SUBSTRING(@temp, 1, @position - 1) + SUBSTRING(@temp, @position + 1, LEN(@temp) - @position)
    END

    declare @return as float
    select @return = MAX(number) from @Numbers
    return @return
END

【讨论】:

  • 注意,你的函数没有参数。
【解决方案2】:

SQL Fiddle Demo

生成txtLEN(txt) 可能的RIGHT() 片段。在第一个非数字字符处修剪每个片段。测试余数是否为int。返回MAX()

SELECT
  txt
 ,MAX(TRY_CONVERT(int,LEFT(RIGHT(txt,i),PATINDEX('%[^0-9]%',RIGHT(txt,i)+' ')-1)))
FROM MyTable
CROSS APPLY (
  SELECT TOP(LEN(txt)) ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) i FROM master.dbo.spt_values a, master.dbo.spt_values b
) x
GROUP BY txt

【讨论】:

    【解决方案3】:

    这是一个标量函数,它将一个字符串作为输入并返回它找到的最大整数(最多 3 位,但从你的问题来看,我假设你正在处理百分比。如果你需要更多位数,无限重复 IF 语句)。

    将其粘贴到 SSMS 中并运行它以创建函数。要调用它,请执行以下操作:

    SELECT dbo.GetLargestNumberFromString(MyStringField) as [Largest Number in String]
    FROM MyMessedUpData
    

    功能:

    CREATE FUNCTION GetLargestNumberFromString
    (
    @s varchar(max)
    ) 
    RETURNS int
    AS
    BEGIN
    
        DECLARE @LargestNumber int, @i int
        SET @i = 1
        SET @LargestNumber = 0
    
        WHILE @i <= LEN(@s)
        BEGIN
    
        IF SUBSTRING(@s, @i, 3) like '[0-9][0-9][0-9]'
            BEGIN
                IF  CAST(SUBSTRING(@s, @i,3) as int) > @LargestNumber OR @LargestNumber IS NULL
                SET @LargestNumber = CAST(SUBSTRING(@s, @i,3) as int);
            END
    
        IF SUBSTRING(@s, @i, 2) like '[0-9][0-9]'
            BEGIN
                IF  CAST(SUBSTRING(@s, @i,2) as int) > @LargestNumber OR @LargestNumber IS NULL
                SET @LargestNumber = CAST(SUBSTRING(@s, @i,2) as int);
            END
    
        IF SUBSTRING(@s, @i, 1) like '[0-9]' OR @LargestNumber IS NULL
            BEGIN
                IF  CAST(SUBSTRING(@s, @i,1) as int) > @LargestNumber
                SET @LargestNumber = CAST(SUBSTRING(@s, @i,1) as int);
            END
    
        SET @i = @i + 1
    
    
        CONTINUE
        END
        RETURN @LargestNumber
    END
    

    【讨论】:

      【解决方案4】:
      1. 按原样将数据拉入 SQL
      2. 编写查询以获取该列中不同的选项列表
      3. 添加一个新列来存储所需的值
      4. 编写更新语句以填充新列

      至于确定最大尺寸,我认为您需要先查看您的数据集,但更新可能很简单:

      DECLARE @COUNTER INT=1000
      While EXISTS (SELECT * FROM <Table> WHERE NewColumn is NULL) AND @COUNTER>=0
      BEGIN
         UPDATE <Table> SET NewColumn=@COUNTER WHERE <SearchColumn> LIKE '%' + CONVERT(VARCHAR,@COUNTER) + '%' AND NewColumn is NULL
      
         SET @COUNTER=@COUNTER-1
      END
      

      【讨论】:

      • 为什么 OP 应该将所有内容都拉到 SQL 中?
      • 好吧,因为听起来他们正在将数据导入表中,所以我不确定使用任何其他机制来提取数据或操作数据的价值
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-21
      • 1970-01-01
      • 1970-01-01
      • 2014-12-13
      • 1970-01-01
      • 2017-11-13
      相关资源
      最近更新 更多