任意顺序的字符串搜索

时间:2018-11-13 08:00:24

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

我有以下两个表:

表1:

CREATE TABLE tbl_str_match_1
(
    enumber int,
    ename varchar(100),
    eaddress varchar(500)
);

INSERT INTO tbl_str_match_1 VALUES(1,'John Mak','Hno 12 Street Road, USA');
INSERT INTO tbl_str_match_1 VALUES(2,'Shai Lee','UK');
INSERT INTO tbl_str_match_1 VALUES(3,'Smith Watson','Street X01 UAE');
INSERT INTO tbl_str_match_1 VALUES(4,'Ray Gibbs','SA 124');

表2:

CREATE TABLE tbl_str_match_4
(
    name varchar(100),
    [address] varchar(500)
);

INSERT INTO tbl_str_match_4 VALUES('Mak John','Street Road, Hno 12, USA');
INSERT INTO tbl_str_match_4 VALUES('Shai A Lee','UK');
INSERT INTO tbl_str_match_4 VALUES('A watson Smeeth ','UAE Street X01');
INSERT INTO tbl_str_match_1 VALUES('Henry Jay','RUS OP124');

我想用传递的数字从表tbl_str_match_1中搜索名称,并在下一次搜索时输入名称作为名称,并从另一个称为tbl_str_match_4的表中找到名称和地址。

注意

  1. 名字可以按照任何顺序排列,例如名字中间名,名字中间名或名字中间名,任何可能性都是可能的。

  2. 我想从第二个表中查找名称和地址,该表具有一个额外的列,即字符串的百分比匹配。

  3. 将进行两次搜索,第一个在表tbl_str_match_1上获取名称,第二个在表tbl_str_match_4上获取名称和地址。

  4. 对于第一条记录John Mak,它应显示与Mak John的100%匹配。

  5. 对于第二条记录,Shai Lee应该显示Shai A LeeA的90%匹配。

  6. 最后Ray Gibbs条记录将不会显示在结果集中,因为它与其他表值不匹配。

-查询:

WITH CTE1 AS
(   
    SELECT ename FROM tbl_str_match_1 WHERE enumber = 1
)
SELECT name,[address] FROM tbl_str_match_4 WHERE name LIKE '%'+(SELECT ename from CTE1)+'%'

预期结果

方案1:如果我通过enumber = 1,那么结果应该是:

    Name        Address                     Matching Percentage
    ------------------------------------------------------------
    Mak John    Street Road, Hno 12, USA    100

方案2:如果我通过enumber = 2,那么结果应该是:

    Name        Address                     Matching Percentage
    ------------------------------------------------------------
    Shai A Lee  UK                          90

方案3:如果我通过enumber = 3,那么结果应该是:

    Name                Address             Matching Percentage
    ------------------------------------------------------------
    A watson Smeeth     UAE Street X01      70

方案4:如果我通过enumber = 4,那么结果应该是:

没有结果,因为我们没有任何相关比赛。

    Name        Address                     Matching Percentage
    ------------------------------------------------------------

3 个答案:

答案 0 :(得分:1)

希望以下帮助。

我首先通过

标记tbl_1和tbl_4名称中的名称

之后,我将tbl_1中的标记与tbl_4比较

有关匹配百分比的问题。 在“ Shai A Lee”的示例中,您有3个匹配项(“ Shai”,“ Lee”)中有2个匹配项(“ Shai”,“ A”,“ Lee”),因此匹配百分比不应为66.67吗? >

<?php 
  if (screen.width <= 720) {
      include "indexm.php";
  } else {
      include "index.php";
  }
?>

答案 1 :(得分:1)

您可以结合使用CTESTRING SPLIT来完成工作

我在tbl_str_match_4中添加了一个Identity列,以简化此操作

 DECLARE @enumber INT = 2

;WITH c1 AS 
( 
  --To split the ename from first  table 

   SELECT s.value AS name
   FROM tbl_str_match_1 t
   CROSS APPLY STRING_SPLIT(t.ename, ' ') AS s
   WHERE enumber=@enumber
)
,c2 AS
( 
   --To split the matching names from second table of matched records

   SELECT t.id,s.value AS name 
   FROM tbl_str_match_4 t
   CROSS APPLY STRING_SPLIT(t.name, ' ') AS s
   WHERE EXISTS(SELECT 1 FROM c1 c WHERE t.name LIKE '%'+c.name+'%')
)
,c3 AS 
( 
   --To calculate the percentage of match

   SELECT id,
   CAST (COUNT(c1.name) AS FLOAT )/ CAST (COUNT(c2.name) AS FLOAT ) * 100 As Percentage
   FROM c2
   LEFT JOIN  c1 on c1.name =c2.name
   GROUP BY id
) 
--display the details
SELECT t.*,c3.Percentage FROM tbl_str_match_4 t
JOIN c3 ON t.Id=c3.Id

FOR DEMO

答案 2 :(得分:0)

希望对您有所帮助。

with CTE1 as

(
Select enumber,Ltrim(SubString(ename,1,Isnull(Nullif(CHARINDEX(' ',ename),0),1000))) As Firstename,

Ltrim(SUBSTRING(ename,CharIndex(' ',ename),
CAse When (CHARINDEX(' ',ename,CHARINDEX(' ',ename)+1)-CHARINDEX(' ',ename))<=0 then 0 
else CHARINDEX(' ',ename,CHARINDEX(' ',ename)+1)-CHARINDEX(' ',ename) end )) as Middleename,

Ltrim(SUBSTRING(ename,Isnull(Nullif(CHARINDEX(' ',ename,Charindex(' ',ename)+1),0),CHARINDEX(' ',ename)),
Case when Charindex(' ',ename)=0 then 0 else LEN(ename) end)) as Lastename

From tbl_str_match_1
),

CTE2 as

(
Select *,Ltrim(SubString(name,1,Isnull(Nullif(CHARINDEX(' ',name),0),1000))) As FirstName,

Ltrim(SUBSTRING(name,CharIndex(' ',name),
CAse When (CHARINDEX(' ',name,CHARINDEX(' ',name)+1)-CHARINDEX(' ',name))<=0 then 0 
else CHARINDEX(' ',name,CHARINDEX(' ',name)+1)-CHARINDEX(' ',name) end )) as MiddleName,

Ltrim(SUBSTRING(name,Isnull(Nullif(CHARINDEX(' ',name,Charindex(' ',name)+1),0),CHARINDEX(' ',name)),
Case when Charindex(' ',name)=0 then 0 else LEN(name) end)) as LastName

From tbl_str_match_4
)

select CTE2.name,CTE2.address from CTE1 inner join CTE2 on  CTE1.Firstename = CTE2.FirstName and CTE1.Lastename = CTE2.LastName
where CTE1.enumber = 1