从SQL中的字符串中删除字符

时间:2017-08-01 16:17:44

标签: sql sql-server

全部,

我在SQL困境中需要一些帮助。我有一个数据表,一个字段可以包含一串多个订单代码。其中一些代码会删除某些后缀和前缀。此外,一些单独的代码是“垃圾代码”表的一部分,所以我需要从字符串中删除它们。例如,“%SBLYMER 8593SB = S8593”需要转换为“8593”,因为%SBLYMER是垃圾代码,我需要从8593SB =剥离SB =,并从S8593剥离S。 8593然后变得重复,我只需要获取单个值并使用该字符串更新我的原始表。

另一个例子是“%36203SBX 4112SB = %% S4112 4112QDB =”需要更新为“%36203SBX 4112 4112QDB =”。

我有一个功能和一个程序来实现这个目标;但是,运行大约需要5分钟,我需要每天使用不同的数据集和两个不同的数据列运行此过程多达100次。有人能提出更有效的方法吗?似乎将单独的代码连接在一起占用了大部分时间。这是我的程序:

--------------------------------------------------------------------------
--  STEP 12.5: Remove suffixes from the result_reflex_code column.      --
--------------------------------------------------------------------------      
IF (OBJECT_ID('tempdb..#convertReflexCodes') Is Not Null)
    BEGIN
        DROP Table #convertReflexCodes
    END 
;
--  split the result_reflex_code items into separate records
WITH CTE AS(
    SELECT DISTINCT  t2.result_code
                    , dbo.fnTCSuffix(f.Item) AS reflexCode
    FROM            compendium_8_utilization_temp as t1 INNER JOIN 
                        compendium_8_utilization_temp as t2 ON t1.util_id = t2.util_id
        CROSS Apply dbo.SplitStrings(t1.result_reflex_code, CHAR(10)) as f
    WHERE t2.result_code != ''
        AND NOT EXISTS (SELECT dbo.fnTCSuffix(f.Item) FROM OERDB_Junk_Codes
                        WHERE dbo.fnTCSuffix(f.Item) = OERDB_Junk_Codes.TestCode)
)

--  reconcatenate the separate records into a temp table
SELECT DISTINCT
    result_code,                                        
    STUFF((                                                      
            SELECT CHAR(10) + u.reflexCode                                                     
            FROM CTE as u
            WHERE u.result_code = CTE.result_code                          
            ORDER BY u.reflexCode                                                        
            FOR xml path('')                                                
        ),1,1,'') as CPT_List
INTO #convertReflexCodes                                     
FROM CTE


--  update the final output table
UPDATE  compendium_8_utilization_temp
SET     result_reflex_code = cpt_List
FROM    compendium_8_utilization_temp INNER JOIN
            #convertReflexCodes ON compendium_8_utilization_temp.result_code = #convertReflexCodes.result_code

--------------------------------------------------------------------------
--  STEP 12.6: Remove suffixes from the order_entry_add_code column.    --
--------------------------------------------------------------------------      
IF (OBJECT_ID('tempdb..#convertOEACodes') Is Not Null)
    BEGIN
        DROP Table #convertOEACodes
    END 
;
--  split the result_reflex_code items into separate records
WITH CTE AS(
    SELECT DISTINCT  t2.result_code
                    , dbo.fnTCSuffix(f.item) AS reflexCode
    FROM            compendium_8_utilization_temp as t1 INNER JOIN 
                        compendium_8_utilization_temp as t2 ON t1.util_id = t2.util_id
        CROSS Apply dbo.SplitStrings(t1.order_entry_add_code, CHAR(10)) as f
    WHERE t2.result_code != ''
        AND NOT EXISTS (SELECT dbo.fnTCSuffix(f.Item) FROM OERDB_Junk_Codes
                        WHERE dbo.fnTCSuffix(f.Item) = OERDB_Junk_Codes.TestCode)
)

--  reconcatenate the separate records into a temp table
SELECT DISTINCT
    result_code,                                        
    STUFF((                                                      
            SELECT CHAR(10) + u.reflexCode                                                     
            FROM CTE as u
            WHERE u.result_code = CTE.result_code                          
            ORDER BY u.reflexCode                                                        
            FOR xml path('')                                                
        ),1,1,'') as CPT_List
INTO #convertOEACodes                                     
FROM CTE

--  update the final output table
UPDATE  compendium_8_utilization_temp
SET     order_entry_add_code = cpt_List
FROM    compendium_8_utilization_temp INNER JOIN
            #convertOEACodes ON compendium_8_utilization_temp.result_code = #convertOEACodes.result_code

example of WITH time

编辑包含数据

以下是垃圾代码表的片段:

    CREATE TABLE OERDB_Junk_Codes(
   jl_id    INTEGER  NOT NULL PRIMARY KEY 
  ,TestCode VARCHAR(10) NOT NULL
);
INSERT INTO mytable(jl_id,TestCode) VALUES (2000,'%14742RAMD');
INSERT INTO mytable(jl_id,TestCode) VALUES (2001,'%14744RAMD');
INSERT INTO mytable(jl_id,TestCode) VALUES (2004,'%17222RAMD');
INSERT INTO mytable(jl_id,TestCode) VALUES (2005,'%35083RAMD');
INSERT INTO mytable(jl_id,TestCode) VALUES (2006,'%35092RAMD');
INSERT INTO mytable(jl_id,TestCode) VALUES (2007,'%35093RAMD');
INSERT INTO mytable(jl_id,TestCode) VALUES (2008,'%35094RAMD');
INSERT INTO mytable(jl_id,TestCode) VALUES (2009,'%35095RAMD');
INSERT INTO mytable(jl_id,TestCode) VALUES (2010,'%35096RAMD');
INSERT INTO mytable(jl_id,TestCode) VALUES (2011,'%35097RAMD');
INSERT INTO mytable(jl_id,TestCode) VALUES (2012,'%35098RAMD');
INSERT INTO mytable(jl_id,TestCode) VALUES (2013,'%35099RAMD');
INSERT INTO mytable(jl_id,TestCode) VALUES (2014,'%35100RAMD');
INSERT INTO mytable(jl_id,TestCode) VALUES (2015,'%35101RAMD');
INSERT INTO mytable(jl_id,TestCode) VALUES (2016,'%35084RAMD');
INSERT INTO mytable(jl_id,TestCode) VALUES (2017,'%35102RAMD');
INSERT INTO mytable(jl_id,TestCode) VALUES (2018,'%17223RAMD');
INSERT INTO mytable(jl_id,TestCode) VALUES (2019,'%17224RAMD');
INSERT INTO mytable(jl_id,TestCode) VALUES (2020,'%17225RAMD');
INSERT INTO mytable(jl_id,TestCode) VALUES (2021,'%17226RAMD');
INSERT INTO mytable(jl_id,TestCode) VALUES (2022,'%35085RAMD');
INSERT INTO mytable(jl_id,TestCode) VALUES (2023,'%35086RAMD');
INSERT INTO mytable(jl_id,TestCode) VALUES (2024,'%35087RAMD');
INSERT INTO mytable(jl_id,TestCode) VALUES (2025,'%35088RAMD');
INSERT INTO mytable(jl_id,TestCode) VALUES (2026,'%35089RAMD');
INSERT INTO mytable(jl_id,TestCode) VALUES (2027,'%35090RAMD');
INSERT INTO mytable(jl_id,TestCode) VALUES (2028,'%35091RAMD');
INSERT INTO mytable(jl_id,TestCode) VALUES (2029,'%17222');
INSERT INTO mytable(jl_id,TestCode) VALUES (2030,'%35083');
INSERT INTO mytable(jl_id,TestCode) VALUES (2031,'%35092');
INSERT INTO mytable(jl_id,TestCode) VALUES (2032,'%35093');
INSERT INTO mytable(jl_id,TestCode) VALUES (2033,'%35094');
INSERT INTO mytable(jl_id,TestCode) VALUES (2034,'%35095');
INSERT INTO mytable(jl_id,TestCode) VALUES (2035,'%35096');
INSERT INTO mytable(jl_id,TestCode) VALUES (2036,'%35097');
INSERT INTO mytable(jl_id,TestCode) VALUES (2037,'%35098');
INSERT INTO mytable(jl_id,TestCode) VALUES (2038,'%35099');
INSERT INTO mytable(jl_id,TestCode) VALUES (2039,'%35100');
INSERT INTO mytable(jl_id,TestCode) VALUES (2040,'%35101');
INSERT INTO mytable(jl_id,TestCode) VALUES (2041,'%35084');
INSERT INTO mytable(jl_id,TestCode) VALUES (2042,'%35102');
INSERT INTO mytable(jl_id,TestCode) VALUES (2043,'%17223');
INSERT INTO mytable(jl_id,TestCode) VALUES (2044,'%17224');
INSERT INTO mytable(jl_id,TestCode) VALUES (2045,'%17225');
INSERT INTO mytable(jl_id,TestCode) VALUES (2046,'%17226');
INSERT INTO mytable(jl_id,TestCode) VALUES (2047,'%35085');
INSERT INTO mytable(jl_id,TestCode) VALUES (2048,'%35086');
INSERT INTO mytable(jl_id,TestCode) VALUES (2049,'%35087');
INSERT INTO mytable(jl_id,TestCode) VALUES (2050,'%35088');
INSERT INTO mytable(jl_id,TestCode) VALUES (2051,'%35089');
INSERT INTO mytable(jl_id,TestCode) VALUES (2052,'%35090');
INSERT INTO mytable(jl_id,TestCode) VALUES (2053,'%35091');
INSERT INTO mytable(jl_id,TestCode) VALUES (2054,'%91368RXE');
INSERT INTO mytable(jl_id,TestCode) VALUES (1925,'%8459RQEZ');
INSERT INTO mytable(jl_id,TestCode) VALUES (1926,'%381RQEZ');
INSERT INTO mytable(jl_id,TestCode) VALUES (1928,'%16912RAP');
INSERT INTO mytable(jl_id,TestCode) VALUES (1929,'%16913RAP');
INSERT INTO mytable(jl_id,TestCode) VALUES (1930,'%16914RAP');
INSERT INTO mytable(jl_id,TestCode) VALUES (1931,'%16916RAP');
INSERT INTO mytable(jl_id,TestCode) VALUES (1932,'%16917RAP');
INSERT INTO mytable(jl_id,TestCode) VALUES (1933,'%16918RAP');
INSERT INTO mytable(jl_id,TestCode) VALUES (1934,'%16919RAP');
INSERT INTO mytable(jl_id,TestCode) VALUES (1935,'%16921RAP');
INSERT INTO mytable(jl_id,TestCode) VALUES (1954,'%36204');
INSERT INTO mytable(jl_id,TestCode) VALUES (1955,'%%%SBDIQ');
INSERT INTO mytable(jl_id,TestCode) VALUES (1956,'%SBUARFL');
INSERT INTO mytable(jl_id,TestCode) VALUES (1957,'%AMMS');
INSERT INTO mytable(jl_id,TestCode) VALUES (1958,'%AMMSX');
INSERT INTO mytable(jl_id,TestCode) VALUES (1959,'%APAMPGC');
INSERT INTO mytable(jl_id,TestCode) VALUES (1960,'%APAMPGCX');
INSERT INTO mytable(jl_id,TestCode) VALUES (1961,'%34514RAMD');
INSERT INTO mytable(jl_id,TestCode) VALUES (1962,'%34517RAMD');
INSERT INTO mytable(jl_id,TestCode) VALUES (1963,'%38155RAMD');
INSERT INTO mytable(jl_id,TestCode) VALUES (1964,'%34515RAMD');
INSERT INTO mytable(jl_id,TestCode) VALUES (1965,'%16217RAPX');
INSERT INTO mytable(jl_id,TestCode) VALUES (1966,'%16213RAP');
INSERT INTO mytable(jl_id,TestCode) VALUES (1967,'%16216RAP');
INSERT INTO mytable(jl_id,TestCode) VALUES (1968,'%16218RAP');
INSERT INTO mytable(jl_id,TestCode) VALUES (1969,'%THMS');
INSERT INTO mytable(jl_id,TestCode) VALUES (1970,'%COMS');
INSERT INTO mytable(jl_id,TestCode) VALUES (1971,'%APOPIGCX');
INSERT INTO mytable(jl_id,TestCode) VALUES (1972,'%APPCPGC');
INSERT INTO mytable(jl_id,TestCode) VALUES (1973,'%APPCPGCX');
INSERT INTO mytable(jl_id,TestCode) VALUES (1974,'%APPRPGC');
INSERT INTO mytable(jl_id,TestCode) VALUES (1975,'%APPRPGCX');
INSERT INTO mytable(jl_id,TestCode) VALUES (1976,'%APOPIGC');
INSERT INTO mytable(jl_id,TestCode) VALUES (1977,'%APCOCGC');
INSERT INTO mytable(jl_id,TestCode) VALUES (1978,'%APCOCGCX');

以下是汇编数据的摘要:

    CREATE TABLE compendium_8_utilization_temp(
   util_id              INTEGER  NOT NULL PRIMARY KEY 
  ,seq                  INTEGER  NOT NULL
  ,order_code           VARCHAR(10) NOT NULL
  ,order_entry_add_code VARCHAR(8)
  ,result_code          INTEGER  NOT NULL
  ,result_reflex_code   VARCHAR(274) NOT NULL
  ,type                 VARCHAR(2) NOT NULL
);
INSERT INTO mytable(util_id,seq,order_code,order_entry_add_code,result_code,result_reflex_code,type) VALUES (521570,1519,'2180',NULL,84021000,'%APMTDGC','TE');
INSERT INTO mytable(util_id,seq,order_code,order_entry_add_code,result_code,result_reflex_code,type) VALUES (521571,1520,'2180',NULL,84021100,'%APMTQGC','TE');
INSERT INTO mytable(util_id,seq,order_code,order_entry_add_code,result_code,result_reflex_code,type) VALUES (521572,1521,'2180',NULL,84021200,'%APOPIGC','TE');
INSERT INTO mytable(util_id,seq,order_code,order_entry_add_code,result_code,result_reflex_code,type) VALUES (521577,1526,'2180',NULL,84021700,'%APPCPGC','TE');
INSERT INTO mytable(util_id,seq,order_code,order_entry_add_code,result_code,result_reflex_code,type) VALUES (521578,1527,'2180',NULL,84021900,'%APPRPGC','TE');
INSERT INTO mytable(util_id,seq,order_code,order_entry_add_code,result_code,result_reflex_code,type) VALUES (521579,1528,'2180',NULL,84022400,'%APETOGC','TE');
INSERT INTO mytable(util_id,seq,order_code,order_entry_add_code,result_code,result_reflex_code,type) VALUES (522154,2788,'3020','SBCULHLD',30006415,'%SBCULI %SBNOCULI %SBNOCULI','T');
INSERT INTO mytable(util_id,seq,order_code,order_entry_add_code,result_code,result_reflex_code,type) VALUES (522155,2789,'3020','SBCULHLD',30006515,'%SBCULI %SBNOCULI','T');
INSERT INTO mytable(util_id,seq,order_code,order_entry_add_code,result_code,result_reflex_code,type) VALUES (522156,2790,'3020','SBCULHLD',30006700,'%SBNOCULI %SBCULI %SBNOCULI','T');
INSERT INTO mytable(util_id,seq,order_code,order_entry_add_code,result_code,result_reflex_code,type) VALUES (522170,2796,'3020','SBCULHLD',30007900,'%SBNOCULI %SBCULI','T');
INSERT INTO mytable(util_id,seq,order_code,order_entry_add_code,result_code,result_reflex_code,type) VALUES (522161,2797,'3020','SBCULHLD',30008900,'%SBCULI %SBNOCULI %SBNOCULI','T');
INSERT INTO mytable(util_id,seq,order_code,order_entry_add_code,result_code,result_reflex_code,type) VALUES (544579,2810,'%SBCULI',NULL,75030100,'395SB= 395X=','T');
INSERT INTO mytable(util_id,seq,order_code,order_entry_add_code,result_code,result_reflex_code,type) VALUES (523158,4394,'6462',NULL,55071600,'%35645SB %35645XCA S%35645','T');
INSERT INTO mytable(util_id,seq,order_code,order_entry_add_code,result_code,result_reflex_code,type) VALUES (523240,4489,'6646',NULL,45054600,'%SBLYMER 8593SB= S8593','T');
INSERT INTO mytable(util_id,seq,order_code,order_entry_add_code,result_code,result_reflex_code,type) VALUES (533290,16264,'90072',NULL,45060420,'%36209SBX 255SB= %IN3 37923SB= 34088SB=','TE');
INSERT INTO mytable(util_id,seq,order_code,order_entry_add_code,result_code,result_reflex_code,type) VALUES (533291,16277,'90073',NULL,45060420,'%36209SBX 4942SB= %IN4 16088SB=','TE');

这是fnTCSuffix函数:

    SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER FUNCTION [dbo].[fnTCSuffix]
(
    @testCode nvarchar(50)
)
RETURNS nvarchar(50)
AS
BEGIN
    DECLARE @returnValue nvarchar(50)
    SELECT @returnValue = 
        CASE 
            WHEN @testCode like '%SB'   THEN    LEFT(@testCode, LEN(@testCode) - 2)
            WHEN @testCode like '%SB='  THEN    LEFT(@testCode, LEN(@testCode) - 3)
            WHEN @testCode like '%SBX=' THEN    LEFT(@testCode, LEN(@testCode) - 4)
            WHEN @testCode like '%SBX'  THEN    LEFT(@testCode, LEN(@testCode) - 3)
            WHEN @testCode like '%X='   THEN    LEFT(@testCode, LEN(@testCode) - 2)
            WHEN @testCode like 'S[%]%' THEN    RIGHT(@testCode, LEN(@testCode) -1)
            WHEN @testCode like 'S%' AND CONVERT(varchar(1),substring(@testCode, 2,1)) like '[1-9]' THEN RIGHT(@testCode, LEN(@testCode) -1)
            ELSE @testCode
        END 
    RETURN @returnValue 
END

splitStrings表值函数:

    SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER FUNCTION [dbo].[SplitStrings]
(
    @List       NVARCHAR(MAX),
    @Delimiter  NVARCHAR(255)
)
RETURNS TABLE
AS
    RETURN (SELECT Number = ROW_NUMBER() OVER (ORDER BY Number),
        Item FROM (SELECT Number, Item = LTRIM(RTRIM(SUBSTRING(@List, Number, 
        CHARINDEX(@Delimiter, @List + @Delimiter, Number) - Number)))
    FROM (SELECT ROW_NUMBER() OVER (ORDER BY s1.[object_id])
        FROM sys.all_objects AS s1 CROSS APPLY sys.all_objects) AS n(Number)
    WHERE Number <= CONVERT(INT, LEN(@List))
        AND SUBSTRING(@Delimiter + @List, Number, 1) = @Delimiter
    ) AS y);

1 个答案:

答案 0 :(得分:0)

我能够设计出一个解决方案。它并不优雅,但是通过将源表分解为更小的临时表,该过程可以在几秒而不是几分钟内运行。

    --------------------------------------------------------------------------
--  STEP 12.5: Remove suffixes from the result_reflex_code column.      --
--------------------------------------------------------------------------      
IF (OBJECT_ID('tempdb..#convertReflexCodes') Is Not Null)
    BEGIN
        DROP Table #convertReflexCodes
    END 

IF (OBJECT_ID('tempdb..#utilCodesWithReflexes') Is Not Null)
    BEGIN
        DROP Table #utilCodesWithReflexes
    END             

SELECT DISTINCT   t2.order_code
                , t2.result_code
                , dbo.fnTCSuffix(f.item) AS reflexCode
INTO            #utilCodesWithReflexes
FROM            compendium_8_utilization_temp as t1 INNER JOIN 
                    compendium_8_utilization_temp as t2 ON t1.util_id = t2.util_id
    CROSS Apply dbo.SplitStrings(t1.result_reflex_code, CHAR(10)) as f
WHERE t2.result_code != '' AND LEN(t2.result_reflex_code) > 0

-- nullify any codes that are in the junk list
UPDATE  #utilCodesWithReflexes
SET     reflexCode = Null
WHERE   EXISTS (SELECT TESTCODE 
                FROM OERDB_Junk_Codes 
                WHERE TestCode = reflexCode)

-- strip suffixes from the remaining codes
UPDATE  #utilCodesWithReflexes
SET     reflexCode = dbo.fnTCSuffix(reflexCode)
WHERE   reflexCode IS NOT NULL

--  concatenate the test codes back together            
SELECT DISTINCT
    order_code 
    ,result_code                                        
    ,STUFF((                                                      
            SELECT CHAR(10) + u.reflexCode                                                     
            FROM #utilCodesWithReflexes as u
            WHERE u.result_code = #utilCodesWithReflexes.result_code
                    AND u.order_code = #utilCodesWithReflexes.order_code                        
            ORDER BY u.reflexCode                                                        
            FOR xml path('')                                                
        ),1,1,'') as reflexCodes
INTO    #convertReflexCodes                                     
FROM    #utilCodesWithReflexes

--  update the output table
UPDATE  compendium_8_utilization_temp
SET     result_reflex_code = reflexCodes
FROM    compendium_8_utilization_temp INNER JOIN
            #convertReflexCodes ON compendium_8_utilization_temp.result_code = #convertReflexCodes.result_code  
            AND compendium_8_utilization_temp.order_code = #convertReflexCodes.order_code       


--------------------------------------------------------------------------
--  STEP 12.6: Remove suffixes from the order_entry_add_code column.    --
--------------------------------------------------------------------------      
IF (OBJECT_ID('tempdb..#convertOEACodes') Is Not Null)
    BEGIN
        DROP Table #convertOEACodes
    END

IF (OBJECT_ID('tempdb..#utilCodesWithOEAC') Is Not Null)
    BEGIN
        DROP Table #utilCodesWithOEAC
    END


SELECT DISTINCT   t2.order_code
                , t2.result_code
                , dbo.fnTCSuffix(f.item) AS reflexCode
INTO            #utilCodesWithOEAC
FROM            compendium_8_utilization_temp as t1 INNER JOIN 
                    compendium_8_utilization_temp as t2 ON t1.util_id = t2.util_id
    CROSS Apply dbo.SplitStrings(t1.order_entry_add_code, CHAR(10)) as f
WHERE t2.result_code != '' AND LEN(t2.order_entry_add_code) > 0


-- nullify any codes that are in the junk list
UPDATE  #utilCodesWithOEAC
SET     reflexCode = Null
WHERE   EXISTS (SELECT TESTCODE 
                FROM OERDB_Junk_Codes 
                WHERE TestCode = reflexCode)


-- strip suffixes from the remaining codes
UPDATE  #utilCodesWithOEAC
SET     reflexCode = dbo.fnTCSuffix(reflexCode)
WHERE   reflexCode IS NOT NULL


--  concatenate the test codes back together            
SELECT DISTINCT
    order_code 
    ,result_code                                        
    ,STUFF((                                                      
            SELECT CHAR(10) + u.reflexCode                                                     
            FROM #utilCodesWithOEAC as u
            WHERE u.result_code = #utilCodesWithOEAC.result_code
                    AND u.order_code = #utilCodesWithOEAC.order_code                        
            ORDER BY u.reflexCode                                                        
            FOR xml path('')                                                
        ),1,1,'') as reflexCodes
INTO    #convertOEACodes                                     
FROM    #utilCodesWithOEAC

--  update the output table
UPDATE  compendium_8_utilization_temp
SET     order_entry_add_code = reflexCodes
FROM    compendium_8_utilization_temp INNER JOIN
            #convertOEACodes ON compendium_8_utilization_temp.result_code = #convertOEACodes.result_code    
            AND compendium_8_utilization_temp.order_code = #convertOEACodes.order_code