我的编程空间,编程开发者的网络收藏夹
学习永远不晚

SQL Server计算Jaccard系数—sim(i,j)

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

SQL Server计算Jaccard系数—sim(i,j)

前些天,在Q群里面看到有人请教这样一个问题:在SQL Server中如何用SQL实现以下计算

SQL Server计算Jaccard系数—sim(i,j)

由图得知,该问题是如何计算Jaccard系数。Jaccard系数,又称为Jaccard相似系数(Jaccard similarity coefficient)用于比较有限样本集之间的相似性与差异性。Jaccard系数值越大,样本相似度越高。


SQL Server通过intersect实现交集,union实现并集,如下:


intersect交集

SQL Server计算Jaccard系数—sim(i,j)

SQL Server计算Jaccard系数—sim(i,j)

SQL Server计算Jaccard系数—sim(i,j)

计算交集代码段如下:(1 intersect 0 = null,1 intersect 1 = 1,0 intersect 0 = 0)

SQL Server计算Jaccard系数—sim(i,j)


union并集

SQL Server计算Jaccard系数—sim(i,j)

SQL Server计算Jaccard系数—sim(i,j)

SQL Server计算Jaccard系数—sim(i,j)

计算并集代码段如下:(1 union 0 = 1 0,1 union 1 = 1,0 union 0 = 0)

SQL Server计算Jaccard系数—sim(i,j)


原理简介:

通过sys.columns表获取表的字段名与字段ID,循环字段名,并根据字段名去取到表中对应的值:如字段名为A,那么取ID为1的值:select A from test where id=1,取ID为2的值:select A from test where id=2,

然后将2个值进行交集与并集,字段循环结束后,得到@str_intersect,@str_union,计算比值:len(@str_intersect)*1.0/len(@str_union)


最终结果如下:

SQL Server计算Jaccard系数—sim(i,j)


全部代码如下:(建表,见注释部分)

--create table Test(id int,A INT,B INT,C INT,D INT,E INT,F INT)
--INSERT INTO TEST SELECT 1,1,1,1,0,0,0
--INSERT INTO TEST SELECT 2,0,1,0,1,0,1
--INSERT INTO TEST SELECT 3,1,1,1,1,0,1
--INSERT INTO TEST SELECT 4,1,1,1,0,1,0
--INSERT INTO TEST SELECT 5,0,1,0,1,1,1
--INSERT INTO TEST SELECT 6,0,0,1,0,1,1
--drop table Test_result
--create table Test_result(id int,_1_ numeric(10,4),_2_ numeric(10,4),_3_ numeric(10,4),_4_ numeric(10,4),_5_ numeric(10,4),_6_ numeric(10,4))
--insert into Test_result select 1,null,null,null,null,null,null
--insert into Test_result select 2,null,null,null,null,null,null
--insert into Test_result select 3,null,null,null,null,null,null
--insert into Test_result select 4,null,null,null,null,null,null
--insert into Test_result select 5,null,null,null,null,null,null
--insert into Test_result select 6,null,null,null,null,null,null
SELECT name,column_id  into #test  FROM SYS.COLUMNS WHERE object_id =object_id('dbo.test')
and column_id>1
declare @id_1 int=0,@id_2 int=0,@str_union varchar(max),@a_union int,@sql_union varchar(max),@str_intersect varchar(max),@a_intersect int,@sql_intersect varchar(max)
declare @name varchar(20),@column_id int
create table #a_union(num int)
create table #a_intersect(num int)
declare @min_id int=0,@max_id int=0,@global_min_id int=0,@global_max_id int=0
select @min_id=min(id),@max_id=max(id),@global_min_id=min(id),@global_max_id=max(id) from Test
while(@min_id<=@max_id)
begin
select @id_1=@min_id,@id_2=@global_min_id
while @id_2<=@global_max_id
begin
select @str_union='',@str_intersect=''
while(select count(1) from #test)>0 
begin
select top 1 @name=name,@column_id=column_id from #test order by column_id
select @sql_union='select CASE '+
'WHEN (select count(1) from (
SELECT '+@name+' FROM TEST WHERE ID='+convert(varchar,@id_1)+'
union 
SELECT '+@name+' FROM TEST WHERE ID='+convert(varchar,@id_2)+') as a)>1 THEN 1'
+' WHEN ISNULL((SELECT '+@name+' FROM TEST WHERE ID='+convert(varchar,@id_1)+' UNION  SELECT '
+@name+' FROM TEST WHERE ID='+convert(varchar,@id_2)+'),0)=0 THEN 0 ELSE 1 END'
insert into #a_union
exec(@sql_union)
SELECT @a_union=num from #a_union
delete from #a_union
if(@a_union=1)
select @str_union+=@name
select @sql_intersect='select CASE WHEN ISNULL((SELECT '+@name+' FROM TEST WHERE ID='+convert(varchar,@id_1)+' INTERSECT  SELECT '
+@name+' FROM TEST WHERE ID='+convert(varchar,@id_2)+'),0)=0 THEN 0 ELSE 1 END'
insert into #a_intersect
exec(@sql_intersect)
SELECT @a_intersect=num from #a_intersect
delete from #a_intersect
if(@a_intersect=1)
select @str_intersect+=@name
delete from #test where @name=name and @column_id=column_id
end
insert into #test SELECT name,column_id FROM SYS.COLUMNS WHERE object_id =object_id('dbo.test')
and column_id>1
--select @str_union,@str_intersect,@column_id,@id_1,@id_2
if(@id_2=1) 
   update Test_result set _1_= convert(numeric(10,4),len(@str_intersect)*1.0/len(@str_union)) where id=@id_1
if(@id_2=2) 
   update Test_result set _2_= convert(numeric(10,4),len(@str_intersect)*1.0/len(@str_union)) where id=@id_1
if(@id_2=3) 
   update Test_result set _3_= convert(numeric(10,4),len(@str_intersect)*1.0/len(@str_union)) where id=@id_1
if(@id_2=4) 
   update Test_result set _4_= convert(numeric(10,4),len(@str_intersect)*1.0/len(@str_union)) where id=@id_1
if(@id_2=5) 
   update Test_result set _5_= convert(numeric(10,4),len(@str_intersect)*1.0/len(@str_union)) where id=@id_1
if(@id_2=6) 
   update Test_result set _6_= convert(numeric(10,4),len(@str_intersect)*1.0/len(@str_union)) where id=@id_1
   
set @id_2=@id_2+1
end
set @min_id=@min_id+1
end
drop table #test
drop table #a_union
drop table #a_intersect
-----------
--create table test_str_column(id int,str_columns varchar(max))
--insert into test_str_column select 1,null
--insert into test_str_column select 2,null
--insert into test_str_column select 3,null
--insert into test_str_column select 4,null
--insert into test_str_column select 5,null
--insert into test_str_column select 6,null
select * into #temp_test_table from test
select name,column_id into #tmp_test_columns from sys.columns where object_id=object_id('dbo.test') and column_id>1
declare @id int,@col_name varchar(20),@col_id int,@string_columns varchar(max),@sql_rs varchar(max),@num_1 int
create table #tmp_rs(num int)
while (select count(1) from #temp_test_table)>0
begin
select top 1 @id=id from #temp_test_table order by id
set @string_columns=''
while(select count(1) from #tmp_test_columns)>0
begin
select top 1 @col_name=name,@col_id=column_id from #tmp_test_columns order by column_id
select @sql_rs='select '+@col_name+' from test where id='+convert(varchar,@id)
insert into #tmp_rs
exec(@sql_rs)
select @num_1=num from #tmp_rs
if(@num_1=1)
set @string_columns=@string_columns+@col_name
delete from #tmp_test_columns where @col_name=name and @col_id=column_id
delete from #tmp_rs
end
insert into #tmp_test_columns select name,column_id  from sys.columns where object_id=object_id('dbo.test') and column_id>1
update test_str_column set str_columns=@string_columns where id =@id
delete from #temp_test_table where @id=id
end
drop table  #temp_test_table
drop table #tmp_test_columns
drop table #tmp_rs
select * from test
select * from test_str_column
select * from Test_result


免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

SQL Server计算Jaccard系数—sim(i,j)

下载Word文档到电脑,方便收藏和打印~

下载Word文档

编程热搜

目录