sql 拆字匹配

小小骨头 2018-01-19 11:18:00
1.拆分文字:百度一下我就知道
2.拆分成:
引用

3.匹配文字:

a.百富美我是谁
b.百度一下我就知道
c.百度一下我就什么
d.谷歌一下我就知道

4.需要的结果是:
设定100%的匹配度,结果是b
设定60%的匹配度,结果是b,c,d
...全文
1079 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
zjcxc 2018-01-22
  • 打赏
  • 举报
回复
首选不在数据库中实现,这种东东程序中应该更快 数据库中的实现,可以参考全文检索的方法:data 本身就做分拆存储,这样检索的时候只需要把检索字符串分拆后与 data join 做 COUNT 就行了 data 分拆存储还可以考虑按字分表或分区,这更有利于检索
小小骨头 2018-01-22
  • 打赏
  • 举报
回复
现在的测试结果是1500*120000,1小时45分可以跑完。
小小骨头 2018-01-22
  • 打赏
  • 举报
回复
引用 19 楼 z10843087 的回复:
这种功能尽量在程序里面去实现比较好,为什么选择在数据库中来做
客户不要界面,大神您的代码能解释一下么,看了大概。
OwenZeng_DBA 2018-01-22
  • 打赏
  • 举报
回复
这种功能尽量在程序里面去实现比较好,为什么选择在数据库中来做
小小骨头 2018-01-22
  • 打赏
  • 举报
回复
引用 12 楼 roy_88 的回复:
用T-SQL写一方法给你参照 改改,把拆分条件放在CTE里去处理 e.g.
use Tempdb
go
--> --> 中国风(Roy)生成測試數據
  
if not object_id(N'Tempdb..#Data') is null
    drop table #Data
Go
Create table #Data([Code] nvarchar(21),[Content] nvarchar(28))
Insert #Data
select N'a',N'百富美我是谁' union all
select N'b',N'百度一下我就知道' union all
select N'c',N'百度一下我就什么' union all
select N'd',N'谷歌一下我就知道'
GO
DECLARE @Str NVARCHAR(100) ='百度一下下我就知道'
      , @Len TINYINT       =0;


SET @Len=LEN(@Str);
WITH TNum (Num)
AS
(
    SELECT TOP 100
        ROW_NUMBER() OVER (ORDER BY RAND())
    FROM syscolumns AS a
       , syscolumns AS b)
   , TNum2 (Condition)
AS
(
    SELECT DISTINCT
        SUBSTRING(@Str, Num, 1)
    FROM TNum
    WHERE Num<=@Len)
SELECT *
     , CAST(b.CountQty * 100.0 / (SELECT COUNT(*) FROM TNum2) AS NUMERIC(5, 2)) AS 权重
FROM #Data AS DT
     CROSS APPLY
(SELECT COUNT(*)
 FROM TNum2
 WHERE DT.[Content] LIKE '%'+Condition+'%') b(CountQty)
WHERE b.CountQty>0
ORDER BY 4 DESC;
大神这个方案快了很多了,继续测试中...
nettman 2018-01-21
  • 打赏
  • 举报
回复
关注,学习
日月路明 2018-01-21
  • 打赏
  • 举报
回复
做个记号,大神的思路不错
  • 打赏
  • 举报
回复
mark一下,思路值得学习,我早就想写类似的语句了,总找不到方法
  • 打赏
  • 举报
回复
学习一下,谢谢
中国风 2018-01-20
  • 打赏
  • 举报
回复
用T-SQL写一方法给你参照
改改,把拆分条件放在CTE里去处理

e.g.
use Tempdb
go
--> --> 中国风(Roy)生成測試數據

if not object_id(N'Tempdb..#Data') is null
drop table #Data
Go
Create table #Data([Code] nvarchar(21),[Content] nvarchar(28))
Insert #Data
select N'a',N'百富美我是谁' union all
select N'b',N'百度一下我就知道' union all
select N'c',N'百度一下我就什么' union all
select N'd',N'谷歌一下我就知道'
GO
DECLARE @Str NVARCHAR(100) ='百度一下下我就知道'
, @Len TINYINT =0;


SET @Len=LEN(@Str);
WITH TNum (Num)
AS
(
SELECT TOP 100
ROW_NUMBER() OVER (ORDER BY RAND())
FROM syscolumns AS a
, syscolumns AS b)
, TNum2 (Condition)
AS
(
SELECT DISTINCT
SUBSTRING(@Str, Num, 1)
FROM TNum
WHERE Num<=@Len)
SELECT *
, CAST(b.CountQty * 100.0 / (SELECT COUNT(*) FROM TNum2) AS NUMERIC(5, 2)) AS 权重
FROM #Data AS DT
CROSS APPLY
(SELECT COUNT(*)
FROM TNum2
WHERE DT.[Content] LIKE '%'+Condition+'%') b(CountQty)
WHERE b.CountQty>0
ORDER BY 4 DESC;
中国风 2018-01-20
  • 打赏
  • 举报
回复
这类权重只能交给全文检索或数据量大要用第三方coreseek等去实现 直接用T-SQL去处理,性能低不可取,除非是处理数据,不用考虑性能,数据量不大可考虑用CLR 函数
RINK_1 2018-01-20
  • 打赏
  • 举报
回复


if OBJECT_ID(N'tempdb.dbo.#T') is not null
drop table #T
go

create table #T(col nvarchar(max))

insert into #T
select '百富美我是谁' union all
select '百度一下我就知道' union all
select '百度一下我就什么' union all
select '谷歌一下我就知道' 

declare @str nvarchar(max)

set @str='百度一下我就知道'

select col,(COUNT(*)*1.0)/MAX(qty_char) as mathc_percent
from
(select COUNT(1) over (partition by 1) as qty_char,SUBSTRING(@str,number,1) as single_char 
from master.dbo.spt_values where LEN(@str)>=number and type='p' and number>0) as A
join
(select col,SUBSTRING(col,number,1) as match_char
from master.dbo.spt_values A 
join #T B ON LEN(col)>=number 
where type='p' and number>0) as B on A.single_char=B.match_char
group by col
shoppo0505 2018-01-19
  • 打赏
  • 举报
回复
计算操作没有问题,我想问下源数据有多少? 源数据的数据量影响算法。
小小骨头 2018-01-19
  • 打赏
  • 举报
回复
引用 6 楼 zjcxc 的回复:
全文检索干的事,这个有很多细节的,要看你怎么定义 就算你只是简单的用单字在要搜索的字符串中的匹配个数来算百分比,也还要考虑重复字,字符顺序的问题吧:
恩,顺序不考虑,重复字,我去重过了。有更好的思路吗?
小小骨头 2018-01-19
  • 打赏
  • 举报
回复
对,大神的实现没问题,效率不行。1000×15000条数据对比,一个小时都没跑完。有更好的思路吗?
zjcxc 2018-01-19
  • 打赏
  • 举报
回复
加上你说的数据量,如果要效率的话,个人觉得不能简单的用 SQL 来实现
zjcxc 2018-01-19
  • 打赏
  • 举报
回复
全文检索干的事,这个有很多细节的,要看你怎么定义 就算你只是简单的用单字在要搜索的字符串中的匹配个数来算百分比,也还要考虑重复字,字符顺序的问题吧:
二月十六 2018-01-19
  • 打赏
  • 举报
回复
引用 4 楼 yinjiale 的回复:
大神能解释一下思路吗
把字符串按照单个单个的字符存到临时表中,然后字符串的临时表进行关联查询,查询出来多少个一样的字符,比如5个,然后再除以字符串总长度10,就是匹配的百分比
小小骨头 2018-01-19
  • 打赏
  • 举报
回复
引用 3 楼 sinat_28984567 的回复:
CREATE FUNCTION dbo.MatchPercent
 (
     @SplitString nvarchar(max) 
 )
 RETURNS @SplitStringsTable TABLE  
 (
     [id] int identity(1,1),
     [value] nvarchar(max)
 )
 AS
 BEGIN
     DECLARE @CurrentIndex int;
     DECLARE @len INT = len(@SplitString);
	 DECLARE @ReturnText NVARCHAR(20)

     SELECT @CurrentIndex=1;
     WHILE(@CurrentIndex<=@len)
         BEGIN
                 SELECT @ReturnText=substring(@SplitString,1,1);
                 INSERT INTO @SplitStringsTable([value]) VALUES(@ReturnText);
				 SET @SplitString = STUFF(@SplitString,1,1,'')
				 SET @CurrentIndex = @CurrentIndex+1				 
             END
     RETURN;
 END
GO
--测试数据
if not object_id(N'Tempdb..#T') is null
	drop table #T
Go
Create table #T([col1] nvarchar(21),[col2] nvarchar(28))
Insert #T
select N'a',N'百富美我是谁' union all
select N'b',N'百度一下我就知道' union all
select N'c',N'百度一下我就什么' union all
select N'd',N'谷歌一下我就知道'
Go
--测试数据结束
DECLARE @str NVARCHAR(max)='百度一下我就知道'
SELECT  * ,
        ( CONVERT(FLOAT, ( SELECT   COUNT(1)
                           FROM     dbo.MatchPercent(col2) t1
                                    JOIN dbo.MatchPercent(@str) t2 ON t2.id = t1.id
                                                              AND t2.value = t1.value
                         )) / ( SELECT  COUNT(1)
                                FROM    dbo.MatchPercent(@str)
                              ) ) AS MatchPercent
FROM    #T
然后按照MatchPercent加where条件搜索
大神能解释一下思路吗
二月十六 2018-01-19
  • 打赏
  • 举报
回复
CREATE FUNCTION dbo.MatchPercent
(
@SplitString nvarchar(max)
)
RETURNS @SplitStringsTable TABLE
(
[id] int identity(1,1),
[value] nvarchar(max)
)
AS
BEGIN
DECLARE @CurrentIndex int;
DECLARE @len INT = len(@SplitString);
DECLARE @ReturnText NVARCHAR(20)

SELECT @CurrentIndex=1;
WHILE(@CurrentIndex<=@len)
BEGIN
SELECT @ReturnText=substring(@SplitString,1,1);
INSERT INTO @SplitStringsTable([value]) VALUES(@ReturnText);
SET @SplitString = STUFF(@SplitString,1,1,'')
SET @CurrentIndex = @CurrentIndex+1
END
RETURN;
END
GO


--测试数据
if not object_id(N'Tempdb..#T') is null
drop table #T
Go
Create table #T([col1] nvarchar(21),[col2] nvarchar(28))
Insert #T
select N'a',N'百富美我是谁' union all
select N'b',N'百度一下我就知道' union all
select N'c',N'百度一下我就什么' union all
select N'd',N'谷歌一下我就知道'
Go
--测试数据结束
DECLARE @str NVARCHAR(max)='百度一下我就知道'
SELECT * ,
( CONVERT(FLOAT, ( SELECT COUNT(1)
FROM dbo.MatchPercent(col2) t1
JOIN dbo.MatchPercent(@str) t2 ON t2.id = t1.id
AND t2.value = t1.value
)) / ( SELECT COUNT(1)
FROM dbo.MatchPercent(@str)
) ) AS MatchPercent
FROM #T





然后按照MatchPercent加where条件搜索
加载更多回复(1)

27,580

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 应用实例
社区管理员
  • 应用实例社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧