我想知道字符串的最后一个字符是否为星号*
我有以下内容给了我最后一个字符:
select RIGHT('hello*',1)
但是如何通过匹配将它作为if语句中的条件使用?以下内容不起作用,因为它只返回最后一个字符。
select '*' = RIGHT('hello*',1)
我可以使用正则表达式吗?
答案 0 :(得分:6)
你就在那里。使用:
select '*' = RIGHT('hello*',1)
Sql评估RIGHT
,但认为您想将其别名为*
您可以有条件地使用表达式:
if RIGHT('hello*',1) = '*'
print 'Ends in *'
else
print 'Does not end in *'
您可以在桌子上进行过滤:
select *
from MyTable
where RIGHT(MyColumn, 1) = '*';
虽然表现不会很出色。 编辑:请参阅Karl Kieninger关于如何大大提高此查询性能的想法的答案
答案 1 :(得分:2)
我创建了一个样本以查看它的实际运行情况,但执行计划显示它实际上从未实际获取我对计算列上的索引搜索所期望的索引。所以现在我不确定我的测试有什么问题。如果有人可以指出我的失败,我会纠正答案。
CREATE TABLE Test(
TestData VARCHAR(10)
,TestData_Reverse AS REVERSE(TestData) PERSISTED
,TestData_Right1 AS RIGHT(TestData,1) PERSISTED
)
INSERT INTO Test(TestData) VALUES ('Bob'),('Joe'),('Ed*')
CREATE INDEX IX_Test_TestData ON Test (TestData)
CREATE INDEX IX_Test_TestData_Reverse ON Test (TestData_Reverse)
CREATE INDEX IX_Test_TestData_Right1 ON Test (TestData_Right1)
GO
SELECT * FROM Test WHERE TestData LIKE '%*' --Index Scan
SELECT * FROM Test WHERE RIGHT(TestData,1) = '*' --Table Scan
SELECT * FROM Test WHERE TestData LIKE '*%' --Index Seek
SELECT * FROM Test WHERE TestData_Reverse LIKE '*%' --Table Scan
SELECT * FROM Test WHERE LEFT(TestData_Reverse,1) = '*' --Index Scan
SELECT * FROM Test WHERE TestData_Right1 = '*' --Table Scan
DROP TABLE Test
修改 - 临时修改
这真的很棒 - 你只需要更多数据,所以:
以下是更多数据,在Sql Express 2014上进行的测试:
INSERT INTO Test(TestData)
SELECT o1.name + o2.name from sys.objects o1, sys.objects o2;
UPDATE STATISTICS Test;
SELECT TestData FROM Test WHERE TestData LIKE '%*' --Index Scan IX_Test_TestData *1 .038
SELECT TestData FROM Test WHERE RIGHT(TestData,1) = '*' --Index Seek (IX_Test_TestData_Right1) *2 .003
SELECT TestData FROM Test WHERE TestData LIKE '*%' --Index Seek IX_Test_TestData *3 .003
SELECT TestData FROM Test WHERE TestData_Reverse LIKE '*%' --Index Scan IX_Test_TestData *4 .038
SELECT TestData FROM Test WHERE LEFT(TestData_Reverse,1) = '*' --Index Scan IX_Test_TestData *5 .038
SELECT TestData FROM Test WHERE LEFT(TestData_Right1,1) = '*' --Index Scan IX_Test_TestData_Right1 *5 .031
SELECT TestData FROM Test WITH (INDEX = IX_Test_TestData_Reverse) WHERE TestData_Reverse LIKE '*%' --Index Scan IX_Test_TestData *6 .05
SELECT TestData FROM Test WHERE TestData_Right1 = '*' --Index Seek IX_Test_TestData_Right1 *7 .003
SELECT * FROM Test WHERE REVERSE(TestData) = '*dE' --Index Seek (IX_Test_TestData_Reverse) *8 .006
好消息 IMO是Sql Server能够“理解”RIGHT(TestData,1)
可以替换计算列并使用IX_Test_TestData_Right1
(同样适用于{ {1}} * 8)。这意味着(无可否认,对于非常具体的查询),持久计算列可以隐藏在远离世界的地方,像普通索引一样隐藏在幕后,并且意味着在有限的情况下实际上可以减轻功能的缺乏可以减轻。
w.r.t。例如令人失望的扫描* 4,还值得注意的是测试表是一个堆,并且Sql没有使用LIKE运算符的搜索的一个可能原因是认为对集群的RID查找将超过使用{{ 1}}超过REVERSE
。
我相信实际表格中的最佳策略是使用覆盖索引IX_Test_TestData_Right / IX_Test_TestData_Reverse
原始未反转的列。
TestData
答案 2 :(得分:0)
试试这个:
DECLARE @x NVARCHAR(32) = 'bbbbbbb*aaaaaaa';
IF(LEN(@x)=(SELECT LEN(@x) - CHARINDEX('*', REVERSE(@x)) + 1))
PRINT 'End with *'
ELSE
PRINT 'No end with *'