WHERE子句抑制重复行

Rob*_*ert 0 sql sql-server-2008 sql-server-2008-r2

当主键位于新表上时,由于主键约束导致表复制错误,我遇到了问题.在通过不设置主键进行一些调查时,我能够在源表中找到重复的行,仍然不确定它是如何进入那里的,但我更好奇的是我发现的其余部分.

开始:

我有一个SQL查询,选择完整的表并返回以下内容:

SELECT *
 FROM search_term_suggest
 order by search_term
Run Code Online (Sandbox Code Playgroud)

你可以看到值是重复的,我不得不滚动表格来找到它.

SQL结果

但是当我将查询限制为:

SELECT *
 FROM search_term_suggest
 where search_term = 'b'
Run Code Online (Sandbox Code Playgroud)

你可以看到它筛选出第一个值.数据库上没有触发器或我可以看到的任何会限制选择查询的触发器.

添加了

我正在运行SQL 2008 r2.任何帮助是极大的赞赏.我正在复制表的数据库是一个SQL 2000数据库,当选择使用上面相同的查询时,我得到了我期望的结果.

编辑: search_term是一个varchar(100),search_term_suggest是一个不是视图的表.

Aar*_*and 5

我的猜测:search_term是a CHAR/NCHAR并且有尾随空格(或者由于其他原因正在考虑尾随空格).尝试:

WHERE RTRIM(search_term) = 'b';
Run Code Online (Sandbox Code Playgroud)

您可能还需要消除不受修剪操作影响的制表符/回车符.

WHERE LTRIM(RTRIM(REPLACE(REPLACE(REPLACE(search_term,
  CHAR(9), ''), CHAR(10), ''), CHAR(13), ''))) = 'b';
Run Code Online (Sandbox Code Playgroud)

请注意,上述两个查询都排除了使用索引,因此如果有索引,search_term您可能应该在将列更改为varchar或之后重建它,nvarchar并确保填充设置和空格不会导致问题.

其他猜测:正如@Dems指出的那样,检查第一个查询中两列的长度.同时尝试将where子句更改为以下内容,仅用于调查目的:

WHERE search_term LIKE 'b%'
  AND LEN(search_term) > 1;
Run Code Online (Sandbox Code Playgroud)

如果你在那里得到任何结果,那么你可以说:

DECLARE @val VARCHAR(100), @i INT;

DECLARE c CURSOR LOCAL STATIC READ_ONLY FAST_FORWARD 
  FOR SELECT search_term FROM dbo.search_term_suggest
  WHERE search_term LIKE 'b%'
    AND LEN(search_term) > 1;

OPEN c;

FETCH NEXT FROM c INTO @val;

WHILE @@FETCH_STATUS = 0
BEGIN
  SET @i = 1;
  PRINT '-----' + @val + ' (' + RTRIM(LEN(@val)) + ')';
  WHILE @i <= LEN(@val)
  BEGIN
    PRINT SUBSTRING(@val, @i, 1) + ' = ' + ASCII(SUBSTRING(@val, @i, 1));
    SET @i = @i + 1;
  END

  FETCH NEXT FROM c INTO @val;
END
CLOSE c;
DEALLOCATE c;
Run Code Online (Sandbox Code Playgroud)

这将帮助您排除故障排除该列以外的内容b- 它可能是您未检查的空格(例如制表符或回车符)或其他非打印字符.