是否可以在不循环的情况下比较T-SQL中以逗号分隔的字符串?

是否可以在不循环的情况下比较T-SQL中以逗号分隔的字符串?,sql,sql-server,tsql,split,Sql,Sql Server,Tsql,Split,假设我有两个表,其中都有一列名为Brand。该值以逗号分隔,例如,如果表中有一个 ACER,ASUS,HP AMD,NVIDIA,SONY HP,GIGABYTE MICROSOFT SAMSUNG,PHILIPS 作为价值。那么另一张桌子就有了 ACER,ASUS,HP AMD,NVIDIA,SONY HP,GIGABYTE MICROSOFT SAMSUNG,PHILIPS 作为价值观 我想比较这些表以获得所有匹配的记录,在我的示例中,宏碁、华硕、惠普和惠普,

假设我有两个表,其中都有一列名为Brand。该值以逗号分隔,例如,如果表中有一个

ACER,ASUS,HP  
AMD,NVIDIA,SONY
HP,GIGABYTE  
MICROSOFT  
SAMSUNG,PHILIPS
作为价值。那么另一张桌子就有了

ACER,ASUS,HP  
AMD,NVIDIA,SONY
HP,GIGABYTE  
MICROSOFT  
SAMSUNG,PHILIPS
作为价值观


我想比较这些表以获得所有匹配的记录,在我的示例中,宏碁、华硕、惠普和惠普,千兆字节匹配,因为它们都有惠普。现在我正在使用循环来实现这一点,我想知道是否有可能在单个查询语法中实现这一点。

在比较分隔字符串时也有同样的问题

您可以使用XML来执行此操作,比较输出并返回相同/不同的值:

declare  @TestInput nvarchar(255)
, @TestInput2 nvarchar(255)

set @TestInput = 'ACER,ASUS,HP'
set @TestInput2 = 'HP,GIGABYTE'



;WITH FirstStringSplit(S1) AS
(
 SELECT CAST('<x>' + REPLACE(@TestInput,',','</x><x>') + '</x>' AS XML)
)
,SecondStringSplit(S2) AS
(
SELECT CAST('<x>' + REPLACE(@TestInput2,',','</x><x>') + '</x>' AS XML)
 )

 SELECT STUFF(
 (
SELECT ',' + part1.value('.','nvarchar(max)')
FROM FirstStringSplit
CROSS APPLY S1.nodes('/x') AS A(part1)
WHERE part1.value('.','nvarchar(max)') IN(SELECT B.part2.value('.','nvarchar(max)')
                                              FROM SecondStringSplit 
                                              CROSS APPLY S2.nodes('/x') AS B(part2)
                                              ) 
FOR XML PATH('')
),1,1,'') as [Same Value]
编辑:


将“Stuff”更改为“XML”

您想要远离循环是正确的

既然你是在2012年,String_Split就不存在了。但是,在野外有任意数量的split/parse TVF函数

示例1-不带TVF

两人都会回来

UDF如果感兴趣


没有优雅或高效的方法可以做到这一点,因为这根本不是RDBMS的工作原理。这些值中的每一个都应该单独位于表中自己的行上——这样,所有这些都变得非常容易查询。如果可能的话,你应该进行相应的重新设计。它可以在没有循环的情况下,在一个查询中实现,但是你需要一个字符串拆分函数来应用于两端,然后连接。如果您使用的是SQL Server 2016+您可以使用STRING_SPLIT函数。互联网上有很多Splitter上的函数不使用while循环。有些使用计数表,有些使用XML,还有CLR函数。此外,正如@EzequielLópezPetrucci刚才所说的,SQL Server 2016具有内置的字符串分割功能。正确的解决方案是规范化数据库。阅读,你会看到很多原因,为什么这个问题的答案绝对是肯定的!如果不可能,请使用字符串拆分函数。@SalmanA:不,我使用的是2012。我不能简单地更改设计并删除整个逗号分隔的列?它有效地获取SELECT子句定义的结果集中的每个单独的结果行,并使它们连接在一起。东西…,1,1,做什么?它将从该结果中删除前导逗号。将此方法称为STUFF是将功劳完全归于错误的工具。
T1_Brand        T2_Brand
ACER,ASUS,HP    HP,GIGABYTE
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('<x>' + replace((Select replace(@String,@Delimiter,'§§Split§§') as [*] For XML Path('')),'§§Split§§','</x><x>')+'</x>' 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,<test>,for,< & >',',')