【问题标题】:How to get exact character diff between two string in sql如何在sql中获得两个字符串之间的精确字符差异
【发布时间】:2016-11-09 08:37:53
【问题描述】:

我有两个字符串,我想在 SQL 中获取两个字符串的内容之间的差异??

例如,

Declare @String1 as varchar(100)='Please check requirement and let me know your feedback.';

Declare @String2 as varchar(100)='Please checkout requirement & let me know your feedback';

结果应该是两个字符串中不常见的单词。

例如结帐,&

【问题讨论】:

  • 从一个例子推理是有问题的。您是否有更多关于预期输入和您正在寻找的结果的示例? IE。你真的在寻找edit distance吗?
  • 理想情况下,不要只是从一个示例更改到一个完全不同的示例。我要求提供多个示例,而您已经删除了已经写过答案的示例。
  • @Damien_The_Unbeliever 我虽然不清楚这个问题,但这就是为什么改变了这个例子。我想找出两个字符串中不常见的单词,任何帮助表示赞赏。
  • 不清楚。您希望在以下用例中看到什么:(1) string1 = 'Hello world' string2 = 'What a wonderful world' (2) string1 = 'stackoverflow.com' string2 = 'stackoverflow'

标签: sql sql-server sql-server-2008 tsql sql-server-2008-r2


【解决方案1】:

此代码将首先将字符串拆分为单个单词,然后检查其他字符串中不存在的单词

Declare @String1 as varchar(100)='Please check requirement and let me know your feedback.';
Declare @String2 as varchar(100)='Please checkout requirement & let me know your feedback';

WITH s1_Splitted AS
(
    SELECT wrd.value('.','nvarchar(max)') AS Word
    FROM
    (SELECT (
            SELECT CAST('<x>' + REPLACE((SELECT @String1 AS [*] FOR XML PATH('')),' ','</x><x>') + '</x>' AS XML)
            ) AS Casted
    ) AS derived
    CROSS APPLY derived.Casted.nodes('/x') AS A(wrd)
)
,s2_Splitted AS
(
    SELECT wrd.value('.','nvarchar(max)') AS Word
    FROM
    (SELECT (
            SELECT CAST('<x>' + REPLACE((SELECT @String2 AS [*] FOR XML PATH('')),' ','</x><x>') + '</x>' AS XML)
            ) AS Casted
    ) AS derived
    CROSS APPLY derived.Casted.nodes('/x') AS A(wrd)
)
SELECT 'only in s1',s1.Word
FROM s1_Splitted AS s1
WHERE NOT EXISTS(SELECT 1 FROM s2_Splitted AS s2 WHERE s2.Word=s1.Word)
UNION ALL
SELECT 'only in s2',s2.Word
FROM s2_Splitted AS s2
WHERE NOT EXISTS(SELECT 1 FROM s1_Splitted AS s1 WHERE s1.Word=s2.Word)

结果(注意: feedback 之后的. 被视为两个不同的词...)

only in s1  and
only in s1  check
only in s1  feedback.
only in s2  &
only in s2  checkout
only in s2  feedback

【讨论】:

    【解决方案2】:

    您可以使用REPLACE,如下所示:

    SELECT REPLACE(CASE WHEN LEN(@String1) < LEN(@String2) THEN @String2 ELSE @String1 END, 
                   CASE WHEN LEN(@String1) < LEN(@String2) THEN @String1 ELSE @String2 END, '')
    

    结果:.com

    【讨论】:

    • 我认为你也应该做相反的替换,因为 @String1 可以是更大的字符串。 +1 虽然。
    • @sagi 我是这么认为的
    【解决方案3】:

    假设@String1 是@String2 的前缀

    select right (@String2,len(@String2)-len(@String1))
    ;
    

    【讨论】:

    • 这不是通用的,仅适用于问题中发布的格式。
    • @Sagi,2个字符串与一个字符串结果的区别有一个通用的定义吗? “stackoverflow”和“高估”有什么区别?在“苹果”和“香蕉”之间?
    • @DuduMarkovitz - 正如我在 cmets 中建议的那样,一个 common 指标是编辑距离,但除了神奇的“我知道有什么区别,让电脑也知道”
    • @Damien_The_Unbeliever,因此“带有字符串结果”。 OP 很清楚所请求的结果,无论它是什么,都是一个字符串。
    • 否,但您的查询仅适用于第二个字符串与第一个字符串相同的情况。反之则行不通,如果开始时有额外的,则行不通。我不是在谈论 'apple' 和 'banana' 之间的区别。顺便说一句 - OP 编辑​​了问题,两个答案都不起作用。
    猜你喜欢
    • 2012-03-10
    • 2014-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多