Is it possible to compare comma delimited string in T-SQL without looping?

后端 未结 2 740
迷失自我
迷失自我 2021-02-11 05:34

Let\'s say I have 2 tables where both has column called Brand. The value is comma delimited so for example if one of the table has

ACER,ASUS,HP  
         


        
2条回答
  •  不知归路
    2021-02-11 06:02

    You are correct in wanting to step away from the loop.

    Since you are on 2012, String_Split() is off the table. However, there are any number of split/parse TVF functions in-the-wild.

    Example 1 - without a TVF

    Declare @T1 table (Brand varchar(50))
    Insert Into @T1 values 
    ('ACER,ASUS,HP'),
    ('AMD,NVIDIA,SONY')
    
    Declare @T2 table (Brand varchar(50))
    Insert Into @T2 values 
    ('HP,GIGABYTE'),
    ('MICROSOFT'),
    ('SAMSUNG,PHILIPS')
    
    
    Select Distinct
           T1_Brand = A.Brand
          ,T2_Brand = B.Brand
     From ( 
            Select Brand,B.*
             From  @T1
             Cross Apply (
                            Select RetVal = LTrim(RTrim(B.i.value('(./text())[1]', 'varchar(max)')))
                            From  (Select x = Cast('' + replace(Brand,',','')+'' as xml)) as A 
                            Cross Apply x.nodes('x') AS B(i)
                         ) B
          ) A
     Join ( 
            Select Brand,B.*
             From  @T2
             Cross Apply (
                            Select RetVal = LTrim(RTrim(B.i.value('(./text())[1]', 'varchar(max)')))
                            From  (Select x = Cast('' + replace(Brand,',','')+'' as xml)) as A 
                            Cross Apply x.nodes('x') AS B(i)
                         ) B
          ) B
     on A.RetVal=B.RetVal
    

    Example 2 - with a TVF

    Select Distinct
           T1_Brand = A.Brand
          ,T2_Brand = B.Brand
     From ( 
            Select Brand,B.*
             From  @T1
             Cross Apply [dbo].[tvf-Str-Parse](Brand,',') B
          ) A
     Join ( 
            Select Brand,B.*
             From  @T2
             Cross Apply [dbo].[tvf-Str-Parse](Brand,',') B
          ) B
     on A.RetVal=B.RetVal
    

    Both Would Return

    T1_Brand        T2_Brand
    ACER,ASUS,HP    HP,GIGABYTE
    

    The UDF if interested

    CREATE FUNCTION [dbo].[tvf-Str-Parse] (@String varchar(max),@Delimiter varchar(10))
    Returns Table 
    As
    Return (  
        Select RetSeq = Row_Number() over (Order By (Select null))
              ,RetVal = LTrim(RTrim(B.i.value('(./text())[1]', 'varchar(max)')))
        From  (Select x = Cast('' + replace((Select replace(@String,@Delimiter,'§§Split§§') as [*] For XML Path('')),'§§Split§§','')+'' as xml).query('.')) as A 
        Cross Apply x.nodes('x') AS B(i)
    );
    --Thanks Shnugo for making this XML safe
    --Select * from [dbo].[tvf-Str-Parse]('Dog,Cat,House,Car',',')
    --Select * from [dbo].[tvf-Str-Parse]('John Cappelletti was here',' ')
    --Select * from [dbo].[tvf-Str-Parse]('this,is,,for,< & >',',')
    

提交回复
热议问题