SQL seleccione onde o campo contém palavras

Preciso de uma selecção que devolva resultados como este:

SELECT * FROM MyTable WHERE Column1 CONTAINS 'word1 word2 word3'

e eu preciso de todos os resultados, isto é, isto inclui cadeias de caracteres com 'word2 word3 word1' ou 'word1 word3 word2' ou qualquer outra combinação dos três.

todas as palavras têm de estar no resultado.

 336
Author: Ben Sutton, 2013-01-12

14 answers

Bastante lento, mas Método de trabalho para incluir qualquer {[5] } de palavras:

SELECT * FROM mytable
WHERE column1 LIKE '%word1%'
   OR column1 LIKE '%word2%'
   OR column1 LIKE '%word3%'

Se precisar de todas as palavras para estar presente, use isto:

SELECT * FROM mytable
WHERE column1 LIKE '%word1%'
  AND column1 LIKE '%word2%'
  AND column1 LIKE '%word3%'

Se você quer algo mais rápido, você precisa olhar em busca de texto completo, e isso é muito específico para cada tipo de banco de dados.

 533
Author: mvp, 2013-01-12 06:27:42

Lembre-se que, se usar LIKE para determinar se uma cadeia de caracteres é uma sub-sequência de outra cadeia de caracteres, terá de escapar aos caracteres correspondentes aos padrões no seu texto de pesquisa.

Se o seu dialecto SQL suporta CHARINDEX, é muito mais fácil usá-lo em vez disso:

SELECT * FROM MyTable
WHERE CHARINDEX('word1', Column1) > 0
  AND CHARINDEX('word2', Column1) > 0
  AND CHARINDEX('word3', Column1) > 0

Também, por favor, tenha em mente que este e o método na resposta aceite só cobrem a correspondência de sub-texto em vez de correspondência de palavras. Assim, por exemplo, a string 'word1word2word3' continuaria a corresponder.

 48
Author: Sam, 2014-09-05 00:38:28

Função

 CREATE FUNCTION [dbo].[fnSplit] ( @sep CHAR(1), @str VARCHAR(512) )
 RETURNS TABLE AS
 RETURN (
           WITH Pieces(pn, start, stop) AS (
           SELECT 1, 1, CHARINDEX(@sep, @str)
           UNION ALL
           SELECT pn + 1, stop + 1, CHARINDEX(@sep, @str, stop + 1)
           FROM Pieces
           WHERE stop > 0
      )

      SELECT
           pn AS Id,
           SUBSTRING(@str, start, CASE WHEN stop > 0 THEN stop - start ELSE 512 END) AS Data
      FROM
           Pieces
 )

Query

 DECLARE @FilterTable TABLE (Data VARCHAR(512))

 INSERT INTO @FilterTable (Data)
 SELECT DISTINCT S.Data
 FROM fnSplit(' ', 'word1 word2 word3') S -- Contains words

 SELECT DISTINCT
      T.*
 FROM
      MyTable T
      INNER JOIN @FilterTable F1 ON T.Column1 LIKE '%' + F1.Data + '%'
      LEFT JOIN @FilterTable F2 ON T.Column1 NOT LIKE '%' + F2.Data + '%'
 WHERE
      F2.Data IS NULL
 16
Author: Eduardo Cuomo, 2014-12-30 18:23:56

Em vez de SELECT * FROM MyTable WHERE Column1 CONTAINS 'word1 word2 word3', adicione e entre essas palavras como:

SELECT * FROM MyTable WHERE Column1 CONTAINS 'word1 And word2 And word3'

Para mais detalhes, veja aqui https://msdn.microsoft.com/en-us/library/ms187787.aspx

Actualizar

Para seleccionar frases, use aspas duplas como:

SELECT * FROM MyTable WHERE Column1 CONTAINS '"Phrase one" And word2 And "Phrase Two"'

p. s. Você tem que ativar a pesquisa de texto completo na tabela antes de usar contém palavra-chave. para mais detalhes, veja aqui https://docs.microsoft.com/en-us/sql/relational-databases/search/get-started-with-full-text-search

 9
Author: messed-up, 2018-03-20 12:22:56
SELECT * FROM MyTable WHERE 
Column1 LIKE '%word1%'
AND Column1 LIKE '%word2%'
AND Column1 LIKE  '%word3%'

Alterado OR para AND com base em Editar para questionar.

 5
Author: Jon Crowell, 2013-01-12 06:30:41
Se só quiseres encontrar uma correspondência.
SELECT * FROM MyTable WHERE INSTR('word1 word2 word3',Column1)<>0

Servidor SQL:

CHARINDEX(Column1, 'word1 word2 word3', 1)<>0
Para obter a correspondência exacta. O exemplo (';a;ab;ac;',';b;') não terá correspondência.
SELECT * FROM MyTable WHERE INSTR(';word1;word2;word3;',';'||Column1||';')<>0
 5
Author: Joshua Balan, 2016-02-09 15:08:09

Se estiver a usar a base de Dados Oracle , então poderá conseguir isto usando contains query. Contains querys are faster than like query.

Se precisar de todas as palavras

SELECT * FROM MyTable WHERE CONTAINS(Column1,'word1 and word2 and word3', 1) > 0

Se precisar de alguma das palavras

SELECT * FROM MyTable WHERE CONTAINS(Column1,'word1 or word2 or word3', 1) > 0

Contém Índice de necessidade do tipo contexto na sua coluna.

CREATE INDEX SEARCH_IDX ON MyTable(Column) INDEXTYPE IS CTXSYS.CONTEXT
 3
Author: mirmdasif, 2015-06-29 12:15:40

Porque não USAR "in" em vez disso?

Select *
from table
where columnname in (word1, word2, word3)
 1
Author: Michael Angerbauer, 2017-11-10 02:31:55
SELECT * FROM MyTable WHERE Column1 Like "*word*"

Isto irá mostrar todos os registos onde column1 tem um valor parcial que contém word.

 0
Author: Jino, 2016-12-27 08:40:37

Tente usar a" pesquisa de tesarus " no índice de texto completo no servidor de MS SQL. Isto é muito melhor do que usar "%" em busca se você tiver milhões de registros. tesarus tem uma pequena quantidade de consumo de memória do que os outros. tente procurar nestas funções:)

 0
Author: Daryl Arenas, 2017-03-31 02:35:13

A melhor maneira é fazer um índice de texto completo numa coluna do quadro e utilizar conter em vez de

SELECT * FROM MyTable WHERE 
contains(Column1 , N'word1' )
AND contains(Column1 , N'word2' )
AND contains(Column1 , N'word3' )
 0
Author: MiladAhmadi, 2017-10-14 06:34:04

Uma das maneiras mais fáceis de alcançar o que é mencionado na pergunta é usando contém com perto ou '~'. Por exemplo, as seguintes consultas dar-nos-iam todas as colunas que incluem especificamente word1, word2 e word3.

SELECT * FROM MyTable WHERE CONTAINS(Column1, 'word1 NEAR word2 NEAR word3')

SELECT * FROM MyTable WHERE CONTAINS(Column1, 'word1 ~ word2 ~ word3')

Além disso, CONTAINSTABLE devolve um rank para cada documento com base na proximidade de "word1", "word2" e "word3". Por exemplo, se um documento contém a frase, "o word1 é word2 e word3", seu ranking seria alto porque o os termos estão mais próximos uns dos outros do que em outros documentos.

Uma outra coisa que gostaria de acrescentar é que também podemos usar proximity_term para encontrar colunas onde as palavras estão dentro de uma distância específica entre elas dentro da frase da coluna.

 0
Author: Anastasios Selmanis, 2018-05-01 16:06:57
DECLARE @SearchStr nvarchar(100)
SET @SearchStr = ' '



CREATE TABLE #Results (ColumnName nvarchar(370), ColumnValue nvarchar(3630))

SET NOCOUNT ON

DECLARE @TableName nvarchar(256), @ColumnName nvarchar(128), @SearchStr2 nvarchar(110)
SET  @TableName = ''
SET @SearchStr2 = QUOTENAME('%' + @SearchStr + '%','''')

WHILE @TableName IS NOT NULL

BEGIN
    SET @ColumnName = ''
    SET @TableName = 
    (
        SELECT MIN(QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME))
        FROM     INFORMATION_SCHEMA.TABLES
        WHERE         TABLE_TYPE = 'BASE TABLE'
            AND    QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) > @TableName
            AND    OBJECTPROPERTY(
                    OBJECT_ID(
                        QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME)
                         ), 'IsMSShipped'
                           ) = 0
    )

    WHILE (@TableName IS NOT NULL) AND (@ColumnName IS NOT NULL)

    BEGIN
        SET @ColumnName =
        (
            SELECT MIN(QUOTENAME(COLUMN_NAME))
            FROM     INFORMATION_SCHEMA.COLUMNS
            WHERE         TABLE_SCHEMA    = PARSENAME(@TableName, 2)
                AND    TABLE_NAME    = PARSENAME(@TableName, 1)
                AND    DATA_TYPE IN ('char', 'varchar', 'nchar', 'nvarchar', 'int', 'decimal')
                AND    QUOTENAME(COLUMN_NAME) > @ColumnName
        )

        IF @ColumnName IS NOT NULL

        BEGIN
            INSERT INTO #Results
            EXEC
            (
                'SELECT ''' + @TableName + '.' + @ColumnName + ''', LEFT(' + @ColumnName + ', 3630) FROM ' + @TableName + ' (NOLOCK) ' +
                ' WHERE ' + @ColumnName + ' LIKE ' + @SearchStr2
            )
        END
    END   
END

SELECT ColumnName, ColumnValue FROM #Results

DROP TABLE #Results
 -1
Author: user2274887, 2018-03-05 11:02:13
select * from table where name regexp '^word[1-3]$'

Ou

select * from table where name in ('word1','word2','word3')
 -2
Author: vidyadhar, 2014-10-29 00:26:24