说我想要所有姓史密斯的人
SELECT *
FROM Person
WHERE LastName = 'Smith'
以上情况很好。但是,由于我的数据库排序规则是CS,因此LastName
,SmItH
或smith
等SMITH
值不会包含在上述结果中。
我能做到
SELECT *
FROM Person
WHERE UPPER(LastName) = 'SMITH'
哪个可行,但查询不是SARGable。但是,问题在于这将导致表/索引扫描而不是搜索。
我知道我可以更改列或数据库排序规则,但有没有办法让查询SARGable而不进行任何数据库更改?
答案 0 :(得分:1)
您可以通过将查询放在where子句之后来更改查询中的排序规则。您还可以混合where子句中使用的排序规则。 (以下示例除了演示使用两种不同的排序规则外毫无意义。)
SELECT *
FROM sys.objects AS o
WHERE UPPER( o.name ) = o.name COLLATE SQL_Latin1_General_CP1_CS_AS
AND o.name = o.name COLLATE SQL_Latin1_General_CP1_CI_AS
整理测试也可用于案例陈述。
SELECT o.name,
CASE
WHEN UPPER( o.name ) = o.name COLLATE SQL_Latin1_General_CP1_CS_AS
THEN 'Upper Case'
WHEN LOWER( o.name ) = o.name COLLATE SQL_Latin1_General_CP1_CS_AS
THEN 'Lower Case'
ELSE 'Mixed Case'
END
FROM sys.objects AS o
WHERE o.is_ms_shipped = 0
;
请注意,使用UPPER / LOWER只是为了证明包含校对后的大小写敏感性。
答案 1 :(得分:0)
也许T-SQL模式匹配会有所帮助: https://technet.microsoft.com/en-us/library/ms187489(v=sql.105).aspx
它不漂亮,但这应该有效:
SELECT *
FROM Person
WHERE LastName LIKE '[Ss][Mm][Ii][Tt][Hh]'
我不能100%确定SQL Server是否能够使用这种查询的索引。
对于索引来说,这样的事情可能更好:
SELECT *
FROM Person
WHERE LastName LIKE 'S[Mm][Ii][Tt][Hh]'
OR LastName LIKE 's[Mm][Ii][Tt][Hh]'