计算SQL Server中两个字符串之间的公共字符

时间:2018-03-07 16:25:49

标签: sql sql-server linq

我需要一些SQL语句的帮助。

我想计算字符串A和B之间的常用字符。 我有这样的表。

  A      B    Result
---------------------
13456   124      2
13478   344      2
79105   782      1
12457   983      0
41295   129      3
43134   343      2
86761   676      2
55444   545      2

我该怎么做?

2 个答案:

答案 0 :(得分:0)

沿着这些线的标量值函数可以完成这项工作,粗糙和肮脏:

CREATE FUNCTION dbo.CountCommonChars (
@var1 varchar(10), 
@var2 varchar(10)
)
RETURNS INT
AS

BEGIN

declare @i int = 0,
    @s char(1) = '',
    @t int = 0

while @i<=9
begin

set @s = convert(char(1),@i)

set @t = @t + (case when charindex(@s,@var1)>0 
    and charindex(@s,@var2)>0 then 1 else 0 end)

set @i=@i+1

end

RETURN @t;

END

然后是这样的事情:

select dbo.CountCommonChars('12345','316')

会导致2.所以你的最终查询可能是:

select A, B, Result = dbo.CountCommonChars(A,B)
from tbl

答案 1 :(得分:0)

计数表在这里非常有用。我把一个放在我的系统上作为视图。这是我的计数表的代码。它超快,读数为零。

create View [dbo].[cteTally] as

WITH
    E1(N) AS (select 1 from (values (1),(1),(1),(1),(1),(1),(1),(1),(1),(1))dt(n)),
    E2(N) AS (SELECT 1 FROM E1 a, E1 b), --10E+2 or 100 rows
    E4(N) AS (SELECT 1 FROM E2 a, E2 b), --10E+4 or 10,000 rows max
    cteTally(N) AS 
    (
        SELECT  ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E4
    )
select N from cteTally

在我们做任何事情之前,我们需要一些样本数据。为了方便演示,我把它扔进了一个表变量。

declare @Something table (String1 varchar(10), String2 varchar(10))

insert @Something values
('13456', '124')
, ('13478', '344')
, ('79105', '782')
, ('12457', '983')
, ('41295', '129')
, ('43134', '343')
, ('86761', '676')
, ('55444', '545')

现在我们只需要利用这个表来获得优势。这会产生原始问题中所述的所需输出。

select String1
    , String2
    , Result = sum(CharCount)
from
(
    select String1
        , String2
        , Charcount = max(case when CHARINDEX(substring(String2, t.N, 1), String1, 0) > 0 then 1 else 0 end)
    from @Something s
    join cteTally t on t.N <= len(String2)
    group by String1
        , String2
        , substring(String2, t.N, 1)
) x
group by String1
        , String2
order by String1