我正在研究一个有各种药物名称的项目.通常,我会找到类似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的最高值 – 这应该是最长的子串匹配.