Sql 列中的差异数
我想检索一列,列中显示每行字母的差异。比如说 如果您有一个值“test”,而另一行有一个值“testing”,那么“test”和“testing”之间的差异是4个字母。列的数据将是值4Sql 列中的差异数,sql,sql-server,tsql,Sql,Sql Server,Tsql,我想检索一列,列中显示每行字母的差异。比如说 如果您有一个值“test”,而另一行有一个值“testing”,那么“test”和“testing”之间的差异是4个字母。列的数据将是值4 I have reflected about it and I don't know where to begin id || value || category || differences ------------------------------------------------
I have reflected about it and I don't know where to begin
id || value || category || differences
--------------------------------------------------
1 || test || 1 || 4
2 || testing || 1 || null
11 || candy || 2 || -3
12 || ca || 2 || null
在这个场景和上下文中,“Test”和“rest”没有区别。我想您只需要
len()
和lead()
:
您还可以使用如下所示的自连接查询:
--create table tbl (id int, value nvarchar(100), category int);
--insert into tbl values
--(1,N'test',1)
--,(2,N' testing',1)
--,(11,N'candy',2)
--,(12,N'ca',2);
select A.*, LEN(B.value)-LEN(A.value) as difference
from tbl A LEFT JOIN tbl B on A.id +1 =B.id and A.category=B.category
--drop table tbl
更新:我注意到您奇怪地将空间定位在末尾。在计算长度时,SQL server通常不计算尾随空格。下面是对上述问题的破解
select A.*, LEN(B.value+'>')-LEN(A.value+'>') as difference
from tbl A LEFT JOIN tbl B on A.id +1 =B.id and A.category=B.category
正如评论中指出的,在这种情况下,Id可能不是连续的
试试这个:
create table #temp ( rownum int PRIMARY KEY IDENTITY(1,1), id int, value nvarchar(100), category int)
insert into #temp (id, value, category)
select id, value, category from tbl order by id asc
select A.id, A.value, A.category, LEN(B.value+'>')-LEN(A.value+'>') as difference
from #temp A LEFT JOIN #temp B on A.rownum +1 =B.rownum and A.category=B.category
您使用
导联
读取下一条记录。然后将字符串与LIKE或其他字符串函数进行比较:
select
id, value, category,
case when value like next_value + '%' or next_value like value + '%'
then len(next_value) - len(value)
end as differences
from
(
select id, value, category, lead(value) over (order by id) as next_value
from mytable
) this_and_next;
如果只想比较同一类别中的值,请使用分区子句:
lead(value) over (partition by category order by id)
更新:请参见DhruvJoshi在SQL Server的
LEN
上的回答。正如我所假设的,这个函数不计算尾随空格,所以你需要他的技巧,以防你想计算它们。下面是LEN
上的文档,确认了这种行为:我认为您要寻找的是前缀相似性的度量,而不仅仅是计算前缀相似性,这有一些常见的算法。是我以前使用过的一个,我看到它被实现为TSQL函数。下面的答案建议了TSQL中的几个实现,您可以按原样使用它们
(尽管要花时间测试代码并理解方法,而不仅仅是复制代码并使用它,这样,如果出现问题,您就可以理解输出-否则您可能会产生一些技术债务,您将不得不在以后偿还)
确切地说,你想要的距离计算方法将取决于你想要计算某些东西,例如,你把一个替换计数为一个变量或一个删除和一个插入,如果你的字符串足够长,它是否重要,你是否想考虑子字符串移动,诸如此类。
ID 1的差异不是3,ID 11的差异不是-3吗?所以测试和休息之间没有区别吗?ID 2中有一个空格,是的,ID 11中应该是-3。我的缺点是,在这个场景和上下文中,测试和休息没有区别。如果“测试”和“休息”没有区别,那么长度上的简单区别就是一个写得很差的问题。测试和测试4的区别是什么?哦,有趣的是SQL Server不计算尾随空格。我不知道。在这方面,这是最有价值的信息。您的查询假定ID是连续的。但是,在使用IDs时,最好不要做出这样的假设。我尝试了您的代码,并检索到一条消息“关键字“with”附近的语法不正确”。如果此语句是公共表表达式、xmlnamespaces子句或更改跟踪上下文子句,则前一条语句必须以分号结尾。”@KLN:如果消息说“上一条语句必须以分号结尾”,我谦恭地建议您以分号结尾上一条语句(显然是之前的那条语句)。无论如何,游戏ISWAR只是建立一个临时表作为一个例子。你在用这个吗?你没有真正的桌子吗?对不起,我没有真正的桌子。别担心,我有真正的桌子。我把它改了,CTE应该以分号开始。
select
id, value, category,
case when value like next_value + '%' or next_value like value + '%'
then len(next_value) - len(value)
end as differences
from
(
select id, value, category, lead(value) over (order by id) as next_value
from mytable
) this_and_next;
lead(value) over (partition by category order by id)