如何修剪通过select查询的in子句的值

时间:2016-12-30 07:56:07

标签: sql-server-2012 select

下面是简单的SQL查询,用于在条件中选择记录。

--like this I have 6000 usernames
select * from tblUsers where Username in ('abc  ','xyz  ',' pqr  ',' mnop  ' );

我知道有LTrim& sql中的Rtrim用于删除左侧和前后的前导空格。分别对。

我想删除左边和左边的空格在我提供给选择查询的所有用户名中。

注意: -

  • 我想修剪我在in子句中传递的值。(我不想将LTrim& RTrim传递给传递的每个值)。

  • 记录中没有尾随空格,但我在条款中传递的值是从excel&然后粘贴在Visual Studio中。然后使用ALT键我在左边放了'(单引号)&弦的右侧。由于这个原因,一些字符串在右侧尾部有空格。

  

如何在选择查询中使用trim函数?

我正在使用MS SQL Server 2012

7 个答案:

答案 0 :(得分:6)

如果我正确理解了您的问题,那么您将从Excel粘贴到adhoc查询中的IN子句中,如下所示。

enter image description here

尾随空格无关紧要。它仍然匹配字符串foo,没有任何尾随空格。

但你需要确保没有前导空格。

由于数据来源是Excel,为什么不在那里完成呢?

您可以使用公式

= CONCATENATE("'",TRIM(SUBSTITUTE(A1,"'","''")),"',")

enter image description here

然后复制结果(从上面屏幕截图中的B列开始),只需要从最终条目中删除额外的逗号。

答案 1 :(得分:2)

你可以这样做:

select * from tblUsers where LTRIM(RTRIM(Username)) in (ltrim(rtrim('abc')),ltrim(rtrim('xyz')),ltrim(rtrim('pqr')),ltrim(rtrim('mnop')));

但是,如果您有权更新数据库。请删除Username字段中的所有空格。这样的查询真的不好。

答案 2 :(得分:1)

解决问题但仍能从用户名索引中受益的一种方法是使用持久计算列:

<强>设置

-- 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

测试

-- this will use the index (index seek)
select * from tblUsers where UsernameTrimmed in (LTRIM(RTRIM('abc')), LTRIM(RTRIM(' useradmin ')));

这样可以以额外的空间为代价更快地进行检索。

为了摆脱查询构造(以及许多LTRIMRTRIM的丑陋),您可以将搜索到的用户推送到类似tblUsers的表中。< / p>

create table dbo.searchedUsers
(
    Username NVARCHAR(64) NOT NULL,
    UsernameTrimmed AS LTRIM(RTRIM(Username)) PERSISTED
)
GO

将原始值推送到dbo.searchedUsers.Username列,查询应如下所示:

select U.* 
from tblUsers AS U 
   join dbo.searchedUsers AS S ON S.UsernameTrimmed = U.UsernameTrimmed 

大局

在应用程序的服务层(C#)中正确修剪数据会更好,以便桌面的未来客户端可以依赖正确的信息。因此,在将信息插入tblUsers和搜索用户(IN值)时都应执行修剪

答案 3 :(得分:0)

select * 
from tblUsers
where RTRIM(LTRIM(Username)) in ('abc','xyz','pqr','mnop');

答案 4 :(得分:0)

Answer: SELECT * FROM tblUsers WHERE LTRIM(RTRIM(Username)) in ('abc','xyz','pqr','mnop');

但是,请注意,如果您的functions条款中有WHERE,那么该列的indexes就会失效,并会使用 scan而不是seek

我建议您在插入tblUsers

之前清理数据

答案 5 :(得分:0)

我想你可以试试这个:

只需将table2替换为您获取用户名

的表名表单
  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) );

答案 6 :(得分:0)

我分两步完成:

1)填充临时表,所有字符串都带有空格


2)使用子选择进行选择

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)