sql – 查找至少共享X个字符的所有字符串,按相似顺序排序

我正在研究一个有各种药物名称的项目.通常,我会找到类似Proscratinol和Proscratinol XR(延长版)的东西.我想找一个查询,以了解这种性质的所有名称,所以我可以将’父母’药物放在一张桌子中并让这些’儿童’药物参考它,所以当我写一个查询做药物计数时,我我不会重复计算Proscratinol,因为它有XR,CR和其他任何版本.我写了以下内容,以便对它进行一次尝试

;with x
as
(
select   drug_name
    from rx
    group by drug_name
)

select distinct *
    from x,x as x2
    where LEFT(x2.drug_name,5) = LEFT(x.drug_name,5)
    and x.drug_name !=x2.drug_name

这将给我一份名单分享前五个字母的所有药物清单.五是完全随意的.到目前为止我所做的已经足够好了,但我想通过降序来命令结果.所以我想找到他们从左边读的X字符是相同的.

例如Phenytoin和Phepil将是3(他们的前三个字母是相同的)

;用x

(
选择drug_name
    来自rx
    按药物名称分组
)

select   x.drug_name as xDrugName
        ,x2.drug_name as x2DrugName
        ,case when LEFT(x2.drug_name,6) = LEFT(x.drug_name,6) 
            then LEN(left(x.drug_name,6)) else '0' end
    from x,x as x2
    where LEFT(x2.drug_name,5) = LEFT(x.drug_name,5)
    and x.drug_name !=x2.drug_name 
    group by x.drug_name,x2.drug_name

我不需要在上面的查询中将int硬编码到左侧函数中,而是需要该整数表达式来返回两个字符串共享的相似字符数.有什么好办法吗?

最佳答案 这种方法使用数字生成器,然后只测试重叠的长度:

select x.drug_name, x2.drug_name, MAX(c.seqnum) as OverlapLen
from x cross join
     x x2 cross join
     (select ROW_NUMBER() over (order by (select NULL)) seqnum
      from INFORMATION_SCHEMA.COLUMNS c
     ) c
where LEFT(x.drug_name, c.seqnum) = LEFT(x2.drug_name, c.seqnum) and
      len(x.drug_name) >= c.seqnum and len(x2.drug_name) >= c.seqnum
group by x.drug_name, x.drug_name
order by x.drug_name, OverlapLen desc

这假定information_schema.columns具有足够的行用于较长的药物名称.

这将x连接到自身,然后加入一个数字列表. where子句检查三个条件:(1)每个药品名称的左侧部分与seqnum相同; (2)每种药物名称的长度小于或等于seqnum.

聚合然后获取每对并选择seqnum的最高值 – 这应该是最长的子串匹配.

点赞