where子句从sql server中的多列搜索值

时间:2014-01-27 05:59:31

标签: sql sql-server where-clause

我的sql server表有51列,如下所示

ID remarks1 remarks2 。 。 。 remarks50

我需要搜索特定字符串是否存在于至少一个备注字段中,如下例所示

id  remarks1  remarks2   remarks3  remarks4
1   key       nonkey      grabaze   jjjjj
2   uuu       888          8888     kkk
3   888       key          hjhj      kjkj

假设我需要搜索key,其中包含备注1,2,3 .....或50

我可以拥有像

这样的sql
select id from tbl where remarks1 ='key' or remarks2='key' and so on ..

编写或查询最多50列真的不切实际..我们有没有快速的方法?

3 个答案:

答案 0 :(得分:1)

您可以尝试使用以下存储过程。

    CREATE PROCEDURE sp_FindStringInTable @stringToFind VARCHAR(100), @schema sysname, @table sysname 
AS 

DECLARE @sqlCommand VARCHAR(8000) 
DECLARE @where VARCHAR(8000) 
DECLARE @columnName sysname 
DECLARE @cursor VARCHAR(8000) 

BEGIN TRY 
   SET @sqlCommand = 'SELECT * FROM [' + @schema + '].[' + @table + '] WHERE' 
   SET @where = '' 

   SET @cursor = 'DECLARE col_cursor CURSOR FOR SELECT COLUMN_NAME 
   FROM ' + DB_NAME() + '.INFORMATION_SCHEMA.COLUMNS 
   WHERE TABLE_SCHEMA = ''' + @schema + ''' 
   AND TABLE_NAME = ''' + @table + ''' 
   AND DATA_TYPE IN (''char'',''nchar'',''ntext'',''nvarchar'',''text'',''varchar'')' 

   EXEC (@cursor) 

   OPEN col_cursor    
   FETCH NEXT FROM col_cursor INTO @columnName    

   WHILE @@FETCH_STATUS = 0    
   BEGIN    
       IF @where <> '' 
           SET @where = @where + ' OR' 

       SET @where = @where + ' [' + @columnName + '] LIKE ''' + @stringToFind + '''' 
       FETCH NEXT FROM col_cursor INTO @columnName    
   END    

   CLOSE col_cursor    
   DEALLOCATE col_cursor  

   SET @sqlCommand = @sqlCommand + @where 
   --PRINT @sqlCommand 
   EXEC (@sqlCommand)  
END TRY 
BEGIN CATCH 
   PRINT 'There was an error. Check to make sure object exists.' 
   IF CURSOR_STATUS('variable', 'col_cursor') <> -3 
   BEGIN 
       CLOSE col_cursor    
       DEALLOCATE col_cursor  
   END 
END CATCH

存储过程在master数据库中创建,因此您可以在任何数据库中使用它,它需要三个参数:

stringToFind - 这是您要查找的字符串。这可以是一个简单的值'test',也可以使用%通配符,例如'%test%','%test'或'test%'。

架构 - 这是对象的架构所有者

- 这是您要搜索的表名,该过程将搜索表中的所有char,nchar,ntext,nvarchar,text和varchar列

Source

答案 1 :(得分:0)

您可以使用unpivotremarks*列转置为具有公共列名称的行,然后您可以对其进行过滤。 (你需要重复所有51列)。 需要明确消除多个列匹配的情况(即模仿原始or

SELECT DISTINCT ID, Rmk
  FROM
    (SELECT ID, Remarks1, Remarks2, Remarks3, Remarks4
     FROM Remarks) r
     UNPIVOT
       (Rmk FOR RmkCol IN (Remarks1, Remarks2, Remarks3, Remarks4))AS unpvt
  WHERE rmk = 'key';

Sql Fiddle here

但是我建议你重新考虑将其规范化为1到多个Remarks表 - 如果你的表很大,你需要Remark*列上的大量索引。

答案 2 :(得分:0)

从tabl_name中选择remarks1,remarks2,remarks3,remarks4 WHERE CONTAINS((remarks1,remarks2,remarks3,remarks4),'888')ORDER BY id;