我有以下要比较的字符串:
DECLARE @a VARCHAR(20), @b VARCHAR(20)
SET @a = '05Y2203-B10'
--SET @a = '05Y2203-B10B'
SET @b = '05Y2203-B10C'
比较时,我想忽略最后一个字符,但前提是-
之后的子字符串长度为4。
'05Y2203-B10B' --ignore the 'B'
'05Y2203-B10' --do not ignore the '0'
一些例子:
'05Y2203-B10B' = '05Y2203-B10B' --match
'05Y2203-B10B' = '05Y2203-B10C' --match
'05Y2203-B10' = '05Y2203-B10B' --match
'05Y2203-B10' = '05Y2203-B11' --no match
'05Y2203-B10' = '18G9987-B10' --no match
字符串将始终如下所示:
'%-[A-Z][0-9][0-9]' --without last character
'%-[A-Z][0-9][0-9][A-Z]' --with last character
-
之前的子字符串长度可能会有所不同。
到目前为止,我有这个解决方案:
SELECT 1
WHERE CASE WHEN LEN(SUBSTRING(@a, CHARINDEX('-', @a) + 1, 4)) = 4
THEN SUBSTRING(@a, 1, LEN(@a) - 1)
ELSE @a
END
=
CASE WHEN LEN(SUBSTRING(@b, CHARINDEX('-', @b) + 1, 4)) = 4
THEN SUBSTRING(@b, 1, LEN(@b) - 1)
ELSE @b
END
这可行,但它不太可读,特别是如果查询中有更多条件。
这个问题是否有更简单或更优雅的解决方案?
答案 0 :(得分:2)
据我所知,你想要更具可读性(可维护性)的查询,如果是这样,那么你可以编写一个简单的标量值函数来返回你想要的字符串部分并隐藏该函数中的所有复杂性
另外,为了获得更好的性能,您可以为此裁剪数据定义另一个computed column
,并使用该函数存储它而不会拖尾数据。
如果您使用PERSISTED
标记该列,则会对其进行物理存储
运行查询时,请使用此列。
答案 1 :(得分:2)
由于-
之后的子字符串长度为3或4,因此您只需在-
之后获取3个字符。这是代码段
LEFT(@a, CHARINDEX('-', @a) + 3) = LEFT(@b, CHARINDEX('-', @b) + 3)