我想知道,如果一個字符串的最後一個字符是一個星號*
如何匹配TSQL中字符串的最後一個字符?
我有這給我的最後一個字符如下:
select RIGHT('hello*',1)
,但我會怎麼使用它作爲一個條件在if語句中通過匹配嗎?以下不起作用,因爲它只返回最後一個字符。
select '*' = RIGHT('hello*',1)
我可以使用正則表達式嗎?
我想知道,如果一個字符串的最後一個字符是一個星號*
如何匹配TSQL中字符串的最後一個字符?
我有這給我的最後一個字符如下:
select RIGHT('hello*',1)
,但我會怎麼使用它作爲一個條件在if語句中通過匹配嗎?以下不起作用,因爲它只返回最後一個字符。
select '*' = RIGHT('hello*',1)
我可以使用正則表達式嗎?
你只是在那裏。通過使用:
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) = '*';
雖然perfor mance將不會是恆星。 編輯:見卡爾Kieninger的答案如何,大大提高了該查詢
的性能試試這個想法:
DECLARE @x NVARCHAR(32) = 'bbbbbbb*aaaaaaa';
IF(LEN(@x)=(SELECT LEN(@x) - CHARINDEX('*', REVERSE(@x)) + 1))
PRINT 'End with *'
ELSE
PRINT 'No end with *'
StuartLC提到的性能。您可以以索引持久計算列爲代價來提高性能。這種戰術已經在其他地方,如已經提到的幾種:
我創建了一個樣品,看看它在行動,但執行計劃表明,它從來沒有真正採摘提高我對索引期望的索引在計算列上的索引。所以現在我不確定我的測試有什麼問題。如果有人能指出我的失敗,我會更正答案。
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)
可替代d爲計算列並且使用IX_Test_TestData_Right1
(和REVERSE
* 8相同)。這意味着(對於非常具體的查詢)(隱含地,對於非常具體的查詢),持久計算的列可以隱藏在世界後面,像普通索引那樣隱藏在幕後,並且意味着在有限的情況下實際上可以緩解函數缺乏可變性。
w.r.t.令人失望的掃描例如* 4,值得注意的是測試表是一個堆,並且Sql不使用LIKE運算符的可能原因之一是認爲到集羣的RID查找將超過使用IX_Test_TestData_Right/IX_Test_TestData_Reverse
TestData
。 我相信實際表格中的最佳策略是使用原始非反轉列的INCLUDE
的覆蓋索引。
CREATE INDEX IX_Test_TestData_Reverse ON Test (TestData_Reverse) INCLUDE (TestData)
SELECT TestData FROM Test WHERE TestData_Reverse LIKE '*%' --Index Scan IX_Test_TestData .003
這真是太好了,我不知道該SQL能夠替代品具有同等功能持久化計算列(這意味着你也可以給優化搜索,非單調函數的錯覺)。這個替換也發生在確定性標量('WITH SCHEMABINDING')用戶定義的函數上。 – StuartLC
哦,對。 SQL Server剛剛決定使用蠻力的表太小,比嘗試使用其他任何東西都快。我知道。感謝您的幫助。我很想離開臨時編輯,但肯定會這樣做,直到(除非)我有機會充分消化和整合。 –