如何使用T-SQL按字符比较字符串并检查是否包含相同符号?
如何用T-SQL检查两个字符串是否由相同的字符组成
要判断两个字符串是否包含完全相同的唯一字符集合(不管字符出现的次数和顺序),核心思路是先提取每个字符串里的所有不重复字符,再对比这两个集合是否完全一致。下面给你几种实用的实现方式:
方法一:用STRING_SPLIT(SQL Server 2016及以上版本)
如果你的SQL Server版本支持STRING_SPLIT函数,这是最简洁的写法:
DECLARE @str1 NVARCHAR(100) = 'aaabbcd', @str2 NVARCHAR(100) = 'ddbca'; -- 双向检查两个字符集合的差异 IF NOT EXISTS ( -- 找出str1有但str2没有的字符 SELECT value FROM STRING_SPLIT(@str1, '') WHERE value <> '' EXCEPT SELECT value FROM STRING_SPLIT(@str2, '') WHERE value <> '' ) AND NOT EXISTS ( -- 找出str2有但str1没有的字符 SELECT value FROM STRING_SPLIT(@str2, '') WHERE value <> '' EXCEPT SELECT value FROM STRING_SPLIT(@str1, '') WHERE value <> '' ) PRINT 'TRUE' ELSE PRINT 'FALSE'
代码说明:
STRING_SPLIT(@str, '')会把字符串拆分成单个字符的行记录;WHERE value <> ''是为了过滤掉拆分空字符串时产生的空值;- 两次
EXCEPT分别检查两个方向的字符差异,如果都没有结果,说明两个字符串的唯一字符完全一致。
方法二:递归CTE(兼容低版本SQL Server)
如果你的SQL Server版本低于2016,不支持STRING_SPLIT,可以用递归CTE来拆分字符串:
DECLARE @str1 NVARCHAR(100) = 'abcddd', @str2 NVARCHAR(100) = 'cda'; -- 递归拆分第一个字符串并去重 WITH CTE_Str1 AS ( SELECT SUBSTRING(@str1, 1, 1) AS CharVal, 1 AS Pos UNION ALL SELECT SUBSTRING(@str1, Pos + 1, 1), Pos + 1 FROM CTE_Str1 WHERE Pos < LEN(@str1) ), CTE_UniqueStr1 AS ( SELECT DISTINCT CharVal FROM CTE_Str1 WHERE CharVal <> '' ), -- 递归拆分第二个字符串并去重 CTE_Str2 AS ( SELECT SUBSTRING(@str2, 1, 1) AS CharVal, 1 AS Pos UNION ALL SELECT SUBSTRING(@str2, Pos + 1, 1), Pos + 1 FROM CTE_Str2 WHERE Pos < LEN(@str2) ), CTE_UniqueStr2 AS ( SELECT DISTINCT CharVal FROM CTE_Str2 WHERE CharVal <> '' ) -- 对比两个唯一字符集合 IF NOT EXISTS (SELECT CharVal FROM CTE_UniqueStr1 EXCEPT SELECT CharVal FROM CTE_UniqueStr2) AND NOT EXISTS (SELECT CharVal FROM CTE_UniqueStr2 EXCEPT SELECT CharVal FROM CTE_UniqueStr1) PRINT 'TRUE' ELSE PRINT 'FALSE'
方法三:封装成可复用的函数
如果需要多次使用这个判断逻辑,可以把它封装成标量函数,方便调用:
CREATE FUNCTION dbo.HasSameCharacters(@str1 NVARCHAR(MAX), @str2 NVARCHAR(MAX)) RETURNS BIT AS BEGIN DECLARE @result BIT = 0; -- 处理空值/空字符串的边界情况 IF (@str1 IS NULL AND @str2 IS NULL) OR (@str1 = '' AND @str2 = '') SET @result = 1; ELSE IF (@str1 IS NULL OR @str1 = '') OR (@str2 IS NULL OR @str2 = '') SET @result = 0; ELSE BEGIN -- 核心对比逻辑 IF NOT EXISTS ( SELECT value FROM STRING_SPLIT(@str1, '') WHERE value <> '' EXCEPT SELECT value FROM STRING_SPLIT(@str2, '') WHERE value <> '' ) AND NOT EXISTS ( SELECT value FROM STRING_SPLIT(@str2, '') WHERE value <> '' EXCEPT SELECT value FROM STRING_SPLIT(@str1, '') WHERE value <> '' ) SET @result = 1; ELSE SET @result = 0; END RETURN @result; END GO -- 调用示例 SELECT dbo.HasSameCharacters('aaabbcd', 'ddbca') AS Result; -- 返回1(TRUE) SELECT dbo.HasSameCharacters('abcddd', 'cda') AS Result; -- 返回0(FALSE)
注意事项:
- 以上方法都会忽略字符出现的次数,只关注是否存在相同的字符;
- 函数里已经处理了空字符串、NULL值的边界情况,你可以根据自己的需求调整逻辑;
- 如果字符串包含特殊字符(比如空格、标点),这些方法也能正确处理,因为拆分是按单个字符来的。
内容的提问来源于stack exchange,提问作者TriniTY
相关产品推荐
相关产品推荐

