Di que quiero conseguir a todas las personas con el apellido Smith

SELECT *
FROM   Person
WHERE  LastName = 'Smith'

Lo anterior está bien. Sin embargo, como mi clasificación de base de datos es CS, un valor de LastName como SmItH, smith o SMITH no se incluirá en los resultados anteriores.

Yo podría hacer

SELECT *
FROM   Person
WHERE  UPPER(LastName) = 'SMITH' 

Lo que funcionaría, sin embargo, la consulta no es SARGable. Sin embargo, el problema es que esto provocará un escaneo de tabla / índice en lugar de una búsqueda.

Sé que puedo cambiar la colación de la columna o la base de datos, pero ¿hay alguna manera de que pueda hacer que la consulta sea SARGable sin realizar ningún cambio en la base de datos?

0
SEarle1986 14 nov. 2017 a las 19:03

2 respuestas

La mejor respuesta

Puede cambiar la intercalación en su consulta colocándola después de la cláusula where. También puede mezclar las intercalaciones utilizadas dentro de una cláusula where. (El siguiente ejemplo no tiene sentido más allá de la demostración usando dos colaciones diferentes).

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

La prueba de colación también se puede utilizar en una declaración de caso.

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
;

Tenga en cuenta que el uso de UPPER / LOWER fue solo para demostrar la naturaleza sensible a mayúsculas y minúsculas una vez que se incluyeron las intercalaciones.

1
Wes H 14 nov. 2017 a las 20:28

Quizás la coincidencia de patrones T-SQL sería útil: https://technet.microsoft.com/en -us / library / ms187489 (v = sql.105) .aspx

No es bonito, pero esto debería funcionar:

SELECT *
FROM Person
WHERE LastName LIKE '[Ss][Mm][Ii][Tt][Hh]'

No estoy 100% seguro de si SQL Server puede usar índices con este tipo de consulta.

Quizás algo como esto sería mejor para los índices:

SELECT *
FROM Person
WHERE LastName LIKE 'S[Mm][Ii][Tt][Hh]'
OR LastName LIKE 's[Mm][Ii][Tt][Hh]'
0
Gigga 14 nov. 2017 a las 19:43