【问题标题】:Count common characters between two string in SQL Server计算 SQL Server 中两个字符串之间的常见字符
【发布时间】:2018-03-07 16:25:48
【问题描述】:

我需要一些关于 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

我该怎么做?

【问题讨论】:

  • 您是在寻找 sql 语句还是 linq 查询?
  • 我认为你的输出有点偏离。 43134、343 返回 2。但 55444、545 返回 3。那么 86761、676 呢?那返回 2,为什么不是 3?更重要的是你用这个逻辑做什么?这种类型的事情表明数据模型中的某些事情不太正确。
  • 感谢 Sean Lange 的回复。对不起。我已经编辑过了。

标签: sql sql-server linq


【解决方案1】:

计数表在这里将非常有用。我在我的系统上保留一个作为视图。这是我的计数表的代码。它速度超快,读取次数为零。

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

【讨论】:

  • 感谢您的回答。
【解决方案2】:

按照这些思路的标量值函数可以完成这项工作,粗糙而肮脏:

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

【讨论】:

  • 标量函数的性能是出了名的差。添加一个while循环是超级慢东西的秘诀。一个计数表会比一个循环更好。这是一篇关于如何使用计数表代替循环的优秀文章。 sqlservercentral.com/articles/T-SQL/62867
  • 同意,就像我说的,粗鲁和肮脏
  • 感谢您的回答。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-06-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-27
  • 2016-11-13
  • 1970-01-01
相关资源
最近更新 更多