uso - SQL SELECT WHERE campo contiene palabras
sql like multiple values (14)
Necesito una selección que devuelva resultados como este:
SELECT * FROM MyTable WHERE Column1 CONTAINS ''word1 word2 word3''
Y necesito todos los resultados, es decir, esto incluye cadenas con ''word2 word3 word1'' o ''word1 word3 word2'' o cualquier otra combinación de los tres.
Todas las palabras deben estar en el resultado.
Función
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
)
Consulta
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
¿Por qué no usar "en" en su lugar?
SELECT * FROM MyTable WHERE
contains(Column1 , N''word1'' )
AND contains(Column1 , N''word2'' )
AND contains(Column1 , N''word3'' )
En lugar de SELECT * FROM MyTable WHERE Column1 CONTAINS ''word1 word2 word3''
, agregue Y entre esas palabras como:
SELECT * FROM MyTable WHERE Column1 CONTAINS ''word1 And word2 And word3''
Para obtener más información, consulte aquí https://msdn.microsoft.com/en-us/library/ms187787.aspx
ACTUALIZAR
Para seleccionar frases, use comillas dobles como:
SELECT * FROM MyTable WHERE Column1 CONTAINS ''"Phrase one" And word2 And "Phrase Two"''
ps , primero debe habilitar la búsqueda de texto completo en la tabla antes de usar contiene palabra clave. Para obtener más detalles, consulte aquí https://docs.microsoft.com/en-us/sql/relational-databases/search/get-started-with-full-text-search
Más bien lento, pero el método de trabajo para incluir cualquiera de las palabras:
SELECT * FROM mytable
WHERE column1 LIKE ''%word1%''
OR column1 LIKE ''%word2%''
OR column1 LIKE ''%word3%''
Si necesitas que todas las palabras estén presentes, usa esto:
SELECT * FROM mytable
WHERE column1 LIKE ''%word1%''
AND column1 LIKE ''%word2%''
AND column1 LIKE ''%word3%''
Si desea algo más rápido, debe buscar en la búsqueda de texto completo, y esto es muy específico para cada tipo de base de datos.
Si está utilizando la base de datos Oracle , puede lograr esto utilizando la consulta de contenido. Las consultas que contiene son más rápidas que las consultas similares.
Si necesitas todas las palabras
SELECT * FROM MyTable WHERE CONTAINS(Column1,''word1 and word2 and word3'', 1) > 0
Si necesitas alguna de las palabras.
SELECT * FROM MyTable WHERE CONTAINS(Column1,''word1 or word2 or word3'', 1) > 0
Contiene índice de necesidad de tipo CONTEXTO en su columna.
CREATE INDEX SEARCH_IDX ON MyTable(Column) INDEXTYPE IS CTXSYS.CONTEXT
Si solo quieres encontrar una coincidencia.
SELECT * FROM MyTable WHERE INSTR(''word1 word2 word3'',Column1)<>0
Servidor SQL :
CHARINDEX(Column1, ''word1 word2 word3'', 1)<>0
Para obtener la coincidencia exacta. Ejemplo ('';a;ab;ac;'','';b;'')
no obtendrá una coincidencia.
SELECT * FROM MyTable WHERE INSTR('';word1;word2;word3;'','';''||Column1||'';'')<>0
Tenga en cuenta que si usa LIKE
para determinar si una cadena es una subcadena de otra cadena, debe escapar de los caracteres que coinciden con el patrón en su cadena de búsqueda.
Si su dialecto SQL es compatible con CHARINDEX
, es mucho más fácil usarlo:
SELECT * FROM MyTable
WHERE CHARINDEX(''word1'', Column1) > 0
AND CHARINDEX(''word2'', Column1) > 0
AND CHARINDEX(''word3'', Column1) > 0
Además, tenga en cuenta que este y el método en la respuesta aceptada solo cubren la concordancia de subcadenas en lugar de las palabras. Entonces, por ejemplo, la cadena ''word1word2word3''
aún coincidirá.
Una de las maneras más fáciles de lograr lo que se menciona en la pregunta es usando CONTAINS con NEAR o ''~''. Por ejemplo, las siguientes consultas nos darían todas las columnas que incluyen específicamente word1, word2 y word3.
SELECT * FROM MyTable WHERE CONTAINS(Column1, ''word1 NEAR word2 NEAR word3'')
SELECT * FROM MyTable WHERE CONTAINS(Column1, ''word1 ~ word2 ~ word3'')
Además, CONTAINSTABLE devuelve una clasificación para cada documento según la proximidad de "word1", "word2" y "word3". Por ejemplo, si un documento contiene la frase "La palabra 1 es word2 y word3", su clasificación sería alta porque los términos están más cerca unos de otros que en otros documentos.
Otra cosa que me gustaría agregar es que también podemos usar el método de proximidad para encontrar columnas donde las palabras están dentro de una distancia específica entre ellas dentro de la frase de la columna.
intente usar la "búsqueda tesarus" en el índice de texto completo en MS SQL Server. Esto es mucho mejor que usar "%" en la búsqueda si tiene millones de registros. Tesarus tiene una pequeña cantidad de consumo de memoria que los otros. intenta buscar esta funciones :)
la mejor manera es hacer un índice de texto completo en una columna de la tabla y usar contener en lugar de LIKE
SELECT * FROM MyTable WHERE Column1 Like "*word*"
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
SELECT * FROM MyTable WHERE
Column1 LIKE ''%word1%''
AND Column1 LIKE ''%word2%''
AND Column1 LIKE ''%word3%''
Se modificó OR
a AND
según la edición a la pregunta.
Select *
from table
where columnname in (word1, word2, word3)
Esto mostrará todos los registros donde column1
tiene un valor parcial que contiene word
.
select * from table where name regexp ''^word[1-3]$''
o
select * from table where name in (''word1'',''word2'',''word3'')