sql server 2012 - operador - Cómo recortar los valores que pasan la cláusula in de la consulta de selección
like en sql (7)
A continuación se muestra una simple consulta SQL para seleccionar registros usando en condición.
--like this I have 6000 usernames
select * from tblUsers where Username in (''abc '',''xyz '','' pqr '','' mnop '' );
Sé que hay LTrim
& Rtrim
en sql para eliminar los espacios finales principales de izquierda y derecha, respectivamente.
Quiero eliminar los espacios de izquierda y derecha en todos los nombres de usuario que estoy suministrando a la consulta de selección.
Nota : -
Quiero recortar los valores que estoy pasando en la cláusula
in
. ( No quiero pasar LTrim & RTrim a cada valor pasado ).No hay espacio final en los registros pero el valor que paso en la cláusula se copia de Excel y luego se pega en Visual Studio. Luego, usando la tecla ALT pongo ''(comilla simple) en los lados izquierdo y derecho de la cadena. Debido a esto, algunas cadenas tienen espacios en el lado derecho al final.
¿Cómo usar la función de
trim
en la consulta de selección?
Estoy usando MS SQL Server 2012
Creo que puedes probar esto:
Simplemente reemplace la tabla2 con el formulario de nombre de la tabla donde obtiene el nombre de usuario
select * from tblUsers where Username in ((select distinct
STUFF((SELECT distinct '', '' + RTRIM(LTRIM(t1.Username))
from table2 t1
FOR XML PATH(''''), TYPE
).value(''.'', ''NVARCHAR(MAX)'')
,1,2,'''') UserName
from table2 t) );
Lo haría en dos pasos:
1) llene una tabla temporal con todas sus cadenas con espacios en blanco
2) hacer una selección con una subselección
create table a (a char(1))
insert into a values(''a'')
insert into a values(''b'')
insert into a values(''c'')
insert into a values(''d'')
create table #b (atmp char(5))
insert into #b values (''a '')
insert into #b values ('' b'')
insert into #b values ('' c '')
select * from a where a in (select ltrim(rtrim(atmp)) from #b)
Puedes hacer así:
select * from tblUsers where LTRIM(RTRIM(Username)) in (ltrim(rtrim(''abc'')),ltrim(rtrim(''xyz'')),ltrim(rtrim(''pqr'')),ltrim(rtrim(''mnop'')));
Sin embargo, si tiene permiso para actualizar la base de datos. Por favor, elimine todos los espacios en su campo Username
. Realmente no es bueno hacer la consulta de esta manera.
Si entiendo correctamente tu pregunta, estás pegando desde Excel en una cláusula IN
en una consulta adhoc como la siguiente.
Los espacios finales no importan. Seguirá coincidiendo con el string foo
sin espacios finales.
Pero debe asegurarse de que no haya espacios principales.
Como la fuente de los datos es Excel, ¿por qué no solo haces todo allí?
Puedes usar fórmula
= CONCATENATE("''",TRIM(SUBSTITUTE(A1,"''","''''")),"'',")
Luego, copie el resultado (de la columna B en la captura de pantalla anterior) y solo necesita recortar la coma adicional de la entrada final.
Una forma de abordar su problema y aún así poder beneficiarse de un índice de nombre de usuario es usar una columna calculada persistente:
Preparar
-- drop table dbo.tblUsers
create table dbo.tblUsers
(
UserId INT NOT NULL IDENTITY(1, 1) CONSTRAINT PK_UserTest PRIMARY KEY,
Username NVARCHAR(64) NOT NULL,
UsernameTrimmed AS LTRIM(RTRIM(Username)) PERSISTED
)
GO
-- other columns may be included here with INCLUDE (col1, col2)
CREATE INDEX IDX_UserTest ON dbo.tblUsers (UsernameTrimmed)
GO
insert into dbo.tblUsers (Username) VALUES (''abc ''),(''xyz ''),('' pqr ''), ('' mnop ''), (''abc''), ('' useradmin ''), (''etc''), ('' other user '')
GO
-- some mock data to obtain a large number of records
insert into dbo.tblUsers (Username)
select top 20000 SUBSTRING(text, 1, 64) from sys.messages
GO
Prueba
-- this will use the index (index seek)
select * from tblUsers where UsernameTrimmed in (LTRIM(RTRIM(''abc'')), LTRIM(RTRIM('' useradmin '')));
Esto permite una recuperación más rápida a expensas de espacio extra.
Para deshacerse de la construcción de consultas (y la fealdad de muchos LTRIM
y RTRIM
), puede empujar a los usuarios buscados en una tabla que se parece a tblUsers
.
create table dbo.searchedUsers
(
Username NVARCHAR(64) NOT NULL,
UsernameTrimmed AS LTRIM(RTRIM(Username)) PERSISTED
)
GO
Introduzca valores sin dbo.searchedUsers.Username
en la columna dbo.searchedUsers.Username
y la consulta debería verse así:
select U.*
from tblUsers AS U
join dbo.searchedUsers AS S ON S.UsernameTrimmed = U.UsernameTrimmed
El panorama
Es mucho mejor recortar adecuadamente sus datos en la capa de servicio de su aplicación (C #) para que los futuros clientes de su mesa puedan contar con información decente. Por lo tanto, el recorte debe realizarse tanto al insertar información en tblUsers
como al buscar usuarios (valores IN)
select *
from tblUsers
where RTRIM(LTRIM(Username)) in (''abc'',''xyz'',''pqr'',''mnop'');
Answer: SELECT * FROM tblUsers WHERE LTRIM(RTRIM(Username)) in (''abc'',''xyz'',''pqr'',''mnop'');
Sin embargo, tenga en cuenta que si tiene functions
en su cláusula WHERE
se frustra el propósito de tener un indexes
en esa columna y usará un scan
de una seek
.
Yo propondría que limpie sus datos antes de insertarlos en tblUsers