SQL SELECT gdzie pole zawiera słowa

Potrzebuję select, który zwróci wyniki w ten sposób:

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

I potrzebuję wszystkich wyników, tzn. obejmuje to ciągi z 'word2 word3 word1' lub 'word1 word3 word2' lub dowolną inną kombinacją tych trzech.

Wszystkie słowa muszą być w wyniku.

 336
Author: Ben Sutton, 2013-01-12

14 answers

Dość powolny, ale działający sposób na dołączenie dowolnych słów:

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

Jeśli potrzebujesz wszystkich słów, aby były obecne, użyj tego:

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

Jeśli chcesz czegoś szybszego, musisz zajrzeć do wyszukiwania pełnotekstowego, co jest bardzo specyficzne dla każdego typu bazy danych.

 533
Author: mvp,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-12 06:27:42

Zauważ, że jeśli używasz LIKE do określenia, czy łańcuch jest podłańcuchem innego łańcucha, musisz uciec od znaków pasujących do wzorca w wyszukiwanym łańcuchu.

Jeśli twój dialekt SQL obsługuje CHARINDEX, o wiele łatwiej jest go użyć zamiast tego:

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

Należy również pamiętać, że ta i metoda w zaakceptowanej odpowiedzi obejmują tylko dopasowanie podłańcucha, a nie dopasowanie słowa. Na przykład łańcuch 'word1word2word3' nadal będzie pasował.

 48
Author: Sam,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-05 00:38:28

Funkcja

 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
 )

Zapytanie

 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,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-30 18:23:56

Zamiast SELECT * FROM MyTable WHERE Column1 CONTAINS 'word1 word2 word3', Dodaj i między tymi słowami jak:

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

Po szczegóły, zobacz tutaj https://msdn.microsoft.com/en-us/library/ms187787.aspx

UPDATE

Do wybierania fraz, użyj podwójnych cudzysłowów, takich jak:

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

p. s. musisz najpierw włączyć wyszukiwanie pełnotekstowe w tabeli przed użyciem słowa kluczowego contains. więcej szczegółów znajdziesz tutaj https://docs.microsoft.com/en-us/sql/relational-databases/search/get-started-with-full-text-search

 9
Author: messed-up,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-20 12:22:56
SELECT * FROM MyTable WHERE 
Column1 LIKE '%word1%'
AND Column1 LIKE '%word2%'
AND Column1 LIKE  '%word3%'

Zmieniono OR na AND na podstawie edit to question.

 5
Author: Jon Crowell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-12 06:30:41

Jeśli chcesz tylko znaleźć dopasowanie.

SELECT * FROM MyTable WHERE INSTR('word1 word2 word3',Column1)<>0

SQL Server:

CHARINDEX(Column1, 'word1 word2 word3', 1)<>0

Aby uzyskać dokładne dopasowanie. Przykład (';a;ab;ac;',';b;') nie zostanie dopasowany.

SELECT * FROM MyTable WHERE INSTR(';word1;word2;word3;',';'||Column1||';')<>0
 5
Author: Joshua Balan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-09 15:08:09

Jeśli używasz Oracle Database, możesz to osiągnąć za pomocą contains query. Zawiera zapytania są szybsze niż podobne zapytania.

Jeśli potrzebujesz wszystkich słów

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

Jeśli potrzebujesz któregokolwiek ze słów

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

Zawiera indeks potrzeb typu CONTEXT w Twojej kolumnie.

CREATE INDEX SEARCH_IDX ON MyTable(Column) INDEXTYPE IS CTXSYS.CONTEXT
 3
Author: mirmdasif,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-29 12:15:40

Dlaczego nie użyć "w" zamiast?

Select *
from table
where columnname in (word1, word2, word3)
 1
Author: Michael Angerbauer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-10 02:31:55
SELECT * FROM MyTable WHERE Column1 Like "*word*"

Wyświetli wszystkie rekordy, w których column1 ma wartość częściową zawierającą word.

 0
Author: Jino,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-27 08:40:37

Spróbuj użyć "tesarus search" w indeksie pełnotekstowym w MS SQL Server. Jest to o wiele lepsze niż używanie "%" w wyszukiwaniu, jeśli masz miliony rekordów. tesarus mają niewielkie zużycie pamięci niż pozostałe. spróbuj wyszukać tę funkcję:)

 0
Author: Daryl Arenas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-31 02:35:13

Najlepiej zrobić indeks pełnotekstowy na kolumnie w tabeli i użyj contain zamiast LIKE

SELECT * FROM MyTable WHERE 
contains(Column1 , N'word1' )
AND contains(Column1 , N'word2' )
AND contains(Column1 , N'word3' )
 0
Author: MiladAhmadi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-14 06:34:04

Jednym z najprostszych sposobów osiągnięcia tego, o czym mowa w pytaniu, jest użycie CONTAINS z NEAR lub '~'. Na przykład następujące zapytania dałyby nam wszystkie kolumny, które konkretnie zawierają word1, word2 i word3.

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

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

Ponadto CONTAINSTABLE zwraca rangę dla każdego dokumentu w oparciu o bliskość "word1", "word2" i "word3". Na przykład, jeśli dokument zawiera zdanie" word1 to word2 i word3", jego ranking byłby wysoki, ponieważ terminy są bliższe sobie niż w innych dokumentach.

Jeszcze jedną rzeczą, którą chciałbym dodać, jest to, że możemy również użyć proximity_term, aby znaleźć kolumny, w których słowa znajdują się w określonej odległości między nimi wewnątrz frazy Kolumnowej.

 0
Author: Anastasios Selmanis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
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,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-05 11:02:13
select * from table where name regexp '^word[1-3]$'

Lub

select * from table where name in ('word1','word2','word3')
 -2
Author: vidyadhar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-29 00:26:24