Функция SQL разбирает текст из столбца - PullRequest
0 голосов
/ 09 мая 2018

У меня есть таблица с текстом, который я хочу разобрать, и я очень близок к решению, но его там не совсем.у меня есть столбец под названием IndicatorNumerator, и я хочу разобрать, как показано ниже, то есть я хочу, чтобы каждое из значений в квадратных скобках в новой строке.как вы можете видеть из вывода ниже, я получаю повторение для первого значения после минуса.это не происходит для тех, у кого нет минуса.

enter image description here

моя функция выглядит следующим образом:

alter function fn_breakdown (@string varchar(max))
returns @breakdown table
(
    originalstr varchar(max),
    breakdownstr varchar(max)
)
as
begin
    while charindex('r',@string,1) >0
    begin
        insert into @breakdown
        select @string,
        SUBSTRING(@string,CHARINDEX('r',@string,1),CHARINDEX(']',@string,1)-CHARINDEX('r',@string,1))
        set @string = right(@string,len(@string)-CHARINDEX(')',@string,1))
    end
    return
end

aВторое, что я хотел бы сделать, это вернуть те, которые после минус, как минус значение, например.-R101 вместо R101, так как мне нужно вычесть эти значения позже.

Любая помощь, высоко ценимая

ниже должна создать временную таблицу и покажет вам результат, который я получаю.вы увидите, что одна из строк дублирует.я хочу иметь одну строку для каждого значения, начинающегося с 'R' в столбце индикаторного числителя

создать таблицу # temped2 (индикаторный счетчик varchar (max))

вставить в # temped2 select '(SUM([R4]) + SUM ([R1010])) - (SUM ([R1035]) + SUM ([R1034])) '

выбрать * из # temped2 cross apply fn_breakdown (индикатор числителя)

Ответы [ 2 ]

0 голосов
/ 10 мая 2018

Пожалуйста, попробуйте этот код, если вы используете SQL Server 2016 и avove

;WITH cte_date
    AS
    (
        SELECT indicatornumerator, REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(indicatornumerator,'(',''),')',''),'[',''),']',''),'SUM',''),'- ','-') ParsedData 
        FROM #temped2
    )
SELECT *
FROM cte_date
CROSS APPLY STRING_SPLIT(ParsedData, ' ')
WHERE [VALUE] != '+';

Ниже скрипт будет работать старше, чем sql server 2016

CREATE FUNCTION [dbo].[StrParse]
               (@delimiter CHAR(1),  
                @csv       NTEXT)  
RETURNS @tbl TABLE(Keys  NVARCHAR(255))  
AS  

  BEGIN  
    DECLARE  @len INT  
    SET @len = Datalength(@csv)  
    IF NOT @len > 0  
      RETURN  

    DECLARE  @l INT  
    DECLARE  @m INT  

    SET @l = 0  
    SET @m = 0  

    DECLARE  @s VARCHAR(255)  
    DECLARE  @slen INT  

    WHILE @l <= @len  
      BEGIN  

        SET @l = @m + 1--current position  
        SET @m = Charindex(@delimiter,Substring(@csv,@l + 1,255)) 

        IF @m <> 0  
          SET @m = @m + @l  
        --insert @tbl(keys) values(@m)  
        SELECT @slen = CASE   
                         WHEN @m = 0 THEN 255 
                         ELSE @m - @l  
                       END  

        IF @slen > 0  
          BEGIN  
            SET @s = Substring(@csv,@l,@slen)  
            INSERT INTO @tbl  
                       (Keys)  
            SELECT @s  
          END  

        SELECT @l = CASE   
                      WHEN @m = 0 THEN @len + 1  
                      ELSE @m + 1  
                    END 
      END  

    RETURN  
  END

GO

;WITH cte_date
    AS
    (
        SELECT indicatornumerator, REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(indicatornumerator,'(',''),')',''),'[',''),']',''),'SUM',''),'- ','-'),'+ ','') ParsedData 
        FROM #temped2
    )
SELECT *
FROM cte_date
CROSS APPLY dbo.StrParse(' ', ParsedData)
go
0 голосов
/ 10 мая 2018

Загрузите копию ngrams8k , а затем:

-- sample data
DECLARE @yourtable TABLE (IndicatorNumerator varchar(1000));
INSERT @yourtable
SELECT 'SUM([R4]) + SUM([R1010]) - SUM([R50]) + SUM([R200])' UNION ALL
SELECT 'SUM([R554]) + SUM([R210]) - SUM([R500]) + SUM([R999])';

-- Solution
SELECT 
  t.IndicatorNumerator,
  breakdownstr = substring(t.IndicatorNumerator, ng.position+1, n.d-ng.position-1)
FROM @yourtable t
CROSS APPLY dbo.ngrams8k(t.IndicatorNumerator, 2) ng
CROSS APPLY (VALUES (charindex(']',t.IndicatorNumerator, ng.position+1))) n(d)
WHERE ng.token = '[R';

Возвращает:

IndicatorNumerator                                       breakdownstr
-------------------------------------------------------- --------------
SUM([R4]) + SUM([R1010]) - SUM([R50]) + SUM([R200])      R4
SUM([R4]) + SUM([R1010]) - SUM([R50]) + SUM([R200])      R1010
SUM([R4]) + SUM([R1010]) - SUM([R50]) + SUM([R200])      R50
SUM([R4]) + SUM([R1010]) - SUM([R50]) + SUM([R200])      R200
SUM([R554]) + SUM([R210]) - SUM([R500]) + SUM([R999])    R554
SUM([R554]) + SUM([R210]) - SUM([R500]) + SUM([R999])    R210
SUM([R554]) + SUM([R210]) - SUM([R500]) + SUM([R999])    R500
SUM([R554]) + SUM([R210]) - SUM([R500]) + SUM([R999])    R999
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...