mysql - wildcards - starting with sql
Usando SQL LIKE e IN juntos (10)
¿Qué tal si usamos una subcadena con IN?
select * from tablename where substring(column,1,4) IN (''M510'',''M615'',''M515'',''M612'')
¿Hay alguna manera de usar LIKE e IN juntos?
Quiero lograr algo como esto.
SELECT * FROM tablename WHERE column IN (''M510%'', ''M615%'', ''M515%'', ''M612%'');
Entonces, básicamente, quiero poder hacer coincidir la columna con un montón de diferentes cadenas. ¿Hay alguna otra manera de hacer esto con una consulta o tendré que recorrer la matriz de cadenas que estoy buscando?
Lo intenté de otra manera
Digamos que la tabla tiene valores
1 M510
2 M615
3 M515
4 M612
5 M510MM
6 M615NN
7 M515OO
8 M612PP
9 A
10 B
11 C
12 D
Aquí cols 1 a 8 son válidos mientras que el resto de ellos son inválidos
SELECT COL_VAL
FROM SO_LIKE_TABLE SLT
WHERE (SELECT DECODE(SUM(CASE
WHEN INSTR(SLT.COL_VAL, COLUMN_VALUE) > 0 THEN
1
ELSE
0
END),
0,
''FALSE'',
''TRUE'')
FROM TABLE(SYS.DBMS_DEBUG_VC2COLl(''M510'', ''M615'', ''M515'', ''M612''))) =
''TRUE''
Lo que he hecho es usar la función INSTR, he intentado encontrar que el valor en la tabla coincide con cualquiera de los valores como entrada. En caso de que lo haga, devolverá su índice, es decir, mayor que cero. En caso de que el valor de la tabla no coincida con ninguna de las entradas, devolverá cero. Este índice lo he agregado para indicar una coincidencia exitosa.
Parece estar funcionando.
Espero eso ayude.
Para una solución perfectamente dinámica, esto se puede lograr combinando un cursor y una tabla temporal. Con esta solución, no necesita conocer la posición de inicio ni la longitud, y es ampliable sin tener que agregar OR a su consulta SQL.
Para este ejemplo, digamos que desea seleccionar la ID, los Detalles y la fecha de creación de una tabla donde se encuentra una cierta lista de texto dentro de ''Detalles''.
Primero crea una tabla FilterTable con las cadenas de búsqueda en una columna llamada Search.
Como pregunta el iniciador solicitó:
insert into [DATABASE].dbo.FilterTable
select ''M510'' union
select ''M615'' union
select ''M515'' union
select ''M612''
Luego puede filtrar sus datos de la siguiente manera:
DECLARE @DATA NVARCHAR(MAX)
CREATE TABLE #Result (ID uniqueIdentifier, Details nvarchar(MAX), Created datetime)
DECLARE DataCursor CURSOR local forward_only FOR
SELECT ''%'' + Search + ''%''
FROM [DATABASE].dbo.FilterTable
OPEN DataCursor
FETCH NEXT FROM DataCursor INTO @DATA
WHILE @@FETCH_STATUS = 0
BEGIN
insert into #Result
select ID, Details, Created
from [DATABASE].dbo.Table (nolock)
where Details like @DATA
FETCH NEXT FROM DataCursor INTO @DATA
END
CLOSE DataCursor
DEALLOCATE DataCursor
select * from #Result
drop table #Result
Espero que esto haya ayudado
Puede hacerlo en una consulta al unir los LIKE individuales con OR:
SELECT * FROM tablename
WHERE column LIKE ''M510%''
OR column LIKE ''M615%''
OR column LIKE ''M515%''
OR column LIKE ''M612%'';
Solo tenga en cuenta que cosas como LIKE y las funciones por fila no siempre se escalan tan bien. Si su tabla es probable que crezca, puede considerar agregar otra columna a su tabla para almacenar los primeros cuatro caracteres del campo de forma independiente.
Esto duplica los datos, pero puede garantizar que se mantenga constante mediante el uso de activadores de inserción y actualización. A continuación, coloque un índice en esa nueva columna y sus consultas se convertirán en:
SELECT * FROM tablename WHERE newcolumn IN (''M510'',''M615'',''M515'',''M612'');
Esto mueve el costo de cálculo al punto donde es necesario (cuando los datos cambian), no cada vez que lo lee. De hecho, podría ir más allá y tener su nueva columna como un booleano que indica que era uno de los cuatro tipos especiales (si ese grupo de especiales cambiará con poca frecuencia). Entonces la consulta sería aún más rápida:
SELECT * FROM tablename WHERE is_special = 1;
Esta compensación de los requisitos de almacenamiento para la velocidad es un truco útil para bases de datos más grandes: generalmente, el espacio en disco es barato, el gruñido de la CPU es valioso y los datos se leen con mucha más frecuencia que los escritos. Al mover el costo de cálculo a la etapa de escritura, amortiza el costo en todas las lecturas.
Puede usar una subconsulta con comodines:
SELECT ''Valid Expression''
WHERE ''Source Column'' LIKE (SELECT ''%Column'' --FROM TABLE)
O puede usar una sola cadena:
SELECT ''Valid Expression''
WHERE ''Source Column'' LIKE (''%Source%'' + ''%Column%'')
Tendrá que usar varios términos LIKE
, unidos por OR
.
Use la versión más larga de IN, que es un grupo de OR.
SELECT * FROM tablename
WHERE column LIKE ''M510%''
OR column LIKE ''M615%''
OR column LIKE ''M515%''
OR column LIKE ''M612%'';
puedes incluso intentar esto
Función
CREATE FUNCTION [dbo].[fn_Split](@text varchar(8000), @delimiter varchar(20))
RETURNS @Strings TABLE
(
position int IDENTITY PRIMARY KEY,
value varchar(8000)
)
AS
BEGIN
DECLARE @index int
SET @index = -1
WHILE (LEN(@text) > 0)
BEGIN
SET @index = CHARINDEX(@delimiter , @text)
IF (@index = 0) AND (LEN(@text) > 0)
BEGIN
INSERT INTO @Strings VALUES (@text)
BREAK
END
IF (@index > 1)
BEGIN
INSERT INTO @Strings VALUES (LEFT(@text, @index - 1))
SET @text = RIGHT(@text, (LEN(@text) - @index))
END
ELSE
SET @text = RIGHT(@text, (LEN(@text) - @index))
END
RETURN
END
Consulta
select * from my_table inner join (select value from fn_split(''M510'', ''M615'', ''M515'', ''M612'','',''))
as split_table on my_table.column_name like ''%''+split_table.value+''%'';
SELECT * FROM tablename
WHERE column IN
(select column from tablename
where column like ''M510%''
or column like ''M615%''
OR column like ''M515%''
or column like''M612%''
)
substr([column name],
[desired starting position (numeric)],
[# characters to include (numeric)]) in ([complete as usual])
Ejemplo
substr([column name],1,4) in (''M510'',''M615'', ''M515'', ''M612'')