如何在SQL Server中比较这两个字符串?

时间:2018-03-20 21:38:35

标签: sql sql-server xml string-matching

所以我需要将字符串与另一个字符串进行比较,以查看字符串的任何部分是否匹配。这对于检查销售人员ID列表是否与列出到特定GM的销售人员ID或者是否超出该GMs ID列表非常有用:

  ID_SP         ID_GM         NEEDED FIELD (overlap)
  136,338,342   512,338,112         338
  512,112,208   512,338,112         512,112
  587,641,211   512,338,112         null

我正在努力实现这一目标。我猜某种UDF?

我意识到在使用for XML路径('')之前这样做会容易得多,但是我希望找到一个不需要我解开数据的解决方案,因为这会破坏整体数据集的大小。

4 个答案:

答案 0 :(得分:3)

不,你不是这样做的。你会回到原始数据。要获得共同的ID:

select tbob.id
from t tbob join
     t tmary
     on tbob.id = tmary.id and tbob.manager = 'Bob' and tmary.manager = 'Mary';

答案 1 :(得分:1)

由于数据集不是两个原始源,而是一个“连接字段”和一个硬编码字符串字段,它是一个GMID列表(每行的值相同),那么正确答案(从问题的起点开始) )是使用节点('/ M')之类的东西作为Split(a)。

然后你得到这样的东西:

  ID_SP      ID_GM
  136        512,338,112
  338        512,338,112
  342        512,338,112

可以做这样的事情:

  case when  ID_GM not like '%'+ID_SP+'%'then 1 else 0 end as 'indicator'

从这里你可以汇总回来并对指标字段求和,并说如果> 0然后ID_SP存在于ID_GM列表中

希望这有助于其他人。

答案 2 :(得分:0)

- 试试这个

Declare @String1 as varchar(100)='512,112,208';

Declare @String2 as varchar(100)='512,338,112';

WITH FirstStringSplit(S1) AS
(
    SELECT CAST('<x>' + REPLACE(@String1,',','</x><x>') + '</x>' AS XML)
)
,SecondStringSplit(S2) AS
(
    SELECT CAST('<x>' + REPLACE(@String2,',','</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,'')

答案 3 :(得分:0)

戈登是对的,你不应该这样做。这应该用原始数据完成。以下代码将“返回原始数据”并使用简单INNER JOIN解决此问题。

CTE将创建派生表(您要避免的所有行)并检查它们是否相等(不使用索引!提前执行此操作的另一个原因):

DECLARE @tbl TABLE(ID INT IDENTITY,ID_SP VARCHAR(100),ID_GM VARCHAR(100));
INSERT INTO @tbl VALUES
 ('136,338,342','512,338,112')
,('512,112,208','512,338,112')
,('587,641,211','512,338,112');

WITH Splitted AS
(
    SELECT t.*
          ,CAST('<x>' + REPLACE(t.ID_SP,',','</x><x>') + '</x>' AS xml) AS PartedSP
          ,CAST('<x>' + REPLACE(t.ID_GM,',','</x><x>') + '</x>' AS xml) AS PartedGM
    FROM @tbl AS t
)
,SetSP AS
(
    SELECT Splitted.ID
          ,Splitted.ID_SP
          ,x.value('text()[1]','int') AS SP_ID 
    FROM Splitted
    CROSS APPLY PartedSP.nodes('/x') AS A(x)
)
,SetGM AS
(
    SELECT Splitted.ID
          ,Splitted.ID_GM
          ,x.value('text()[1]','int') AS GM_ID 
    FROM Splitted
    CROSS APPLY PartedGM.nodes('/x') AS A(x)
)
,BackToYourRawData AS --Here is the point you should do this in advance!
(
SELECT SetSP.ID
      ,SetSP.SP_ID 
      ,SetGM.GM_ID
FROM SetSP
INNER JOIN SetGM ON SetSP.ID=SetGM.ID 
                 AND SetSP.SP_ID=SetGM.GM_ID
)
SELECT ID
      ,STUFF((
        SELECT ',' + CAST(rd2.SP_ID AS VARCHAR(10))
        FROM BackToYourRawData AS rd2
        WHERE rd.ID=rd2.ID
        ORDER BY rd2.SP_ID
        FOR XML PATH('')),1,1,'') AS CommonID
FROM BackToYourRawData AS rd
GROUP BY ID;

结果

ID  CommonID
1   338
2   112,512