En SQL I (lamentablemente) a menudo tengo que usar " LIKE
" condiciones debido a bases de datos que violan casi todas las reglas de normalización. No puedo cambiar eso ahora. Pero eso es irrelevante para la pregunta.
Además, a menudo uso condiciones como WHERE something in (1,1,2,3,5,8,13,21)
una mejor legibilidad y flexibilidad de mis declaraciones SQL.
¿Hay alguna forma posible de combinar estas dos cosas sin escribir sub-selecciones complicadas?
Quiero algo tan fácil como en WHERE something LIKE ('bla%', '%foo%', 'batz%')
lugar de esto:
WHERE something LIKE 'bla%'
OR something LIKE '%foo%'
OR something LIKE 'batz%'
Estoy trabajando con SQl Server y Oracle aquí, pero estoy interesado si esto es posible en cualquier RDBMS.
like any
/like all
: stackoverflow.com/questions/40475982/sql-like-any-vs-like-all de Teradata . (Para el registro, esto se solicitó en el foro de Oracle Community Ideas community.oracle.com/ideas/11592 )Respuestas:
No hay combinación de LIKE & IN en SQL, mucho menos en TSQL (SQL Server) o PLSQL (Oracle). Parte de la razón de esto es porque la búsqueda de texto completo (FTS) es la alternativa recomendada.
Las implementaciones FTS de Oracle y SQL Server admiten la palabra clave CONTAINS, pero la sintaxis sigue siendo ligeramente diferente:
Oráculo:
Servidor SQL:
La columna que está consultando debe estar indexada en texto completo.
Referencia:
fuente
Si desea que su declaración sea fácilmente legible, puede usar REGEXP_LIKE (disponible desde Oracle versión 10 en adelante).
Una tabla de ejemplo:
La sintaxis original:
Y una consulta simple con REGEXP_LIKE
PERO ...
No lo recomendaría yo mismo debido al rendimiento no tan bueno. Me quedaría con los varios predicados LIKE. Así que los ejemplos fueron solo por diversión.
fuente
estás atrapado con el
a menos que llene una tabla temporal (incluya los comodines con los datos) y únase así:
pruébelo (usando la sintaxis de SQL Server):
SALIDA:
fuente
LIKE 'bla%'
, que en el código de ejemplo del OP? o solo puede hacerLIKE '%bla%'
búsquedas?Con PostgreSQL existe la forma
ANY
oALL
:o
donde la subselección devuelve exactamente una columna de datos.
fuente
LIKE ANY
yLIKE ALL
comunes a todos los dialectos SQL, es decir, parte del núcleo del lenguaje, o específicas de un dialecto?= ANY
o<> ALL
funciona solo en SQL, no en PLSQL, por ejemplo.Otra solución, debería funcionar en cualquier RDBMS:
fuente
Sugeriría usar una función de usuario de TableValue si desea encapsular las técnicas Inner Join o temp table que se muestran arriba. Esto le permitiría leer un poco más claramente.
Después de usar la función de división definida en: http://www.logiclabz.com/sql-server/split-function-in-sql-server-to-break-comma-separated-strings-into-table.aspx
podemos escribir lo siguiente en base a una tabla que creé llamada "Fish" (int id, varchar (50) Name)
Salidas
fuente
Un enfoque sería almacenar las condiciones en una tabla temporal (o variable de tabla en SQL Server) y unirse a eso de esta manera:
fuente
Use una unión interna en su lugar:
fuente
Teradata admite la sintaxis LIKE ALL / ANY :
EDITAR:
jOOQ versión 3.12.0 admite esa sintaxis:
Agregue operadores sintéticos [NO] COMO CUALQUIERA y [NO] COMO TODOS
PostgreSQL
LIKE/ILIKE ANY (ARRAY[])
:demostración de violín db <>
Snowflake también es compatible con LIKE CUALQUIERA / LIKE ALL :
Ejemplo:
fuente
incluso puedes probar esto
Función
Consulta
fuente
Tengo una solución simple, que funciona en postgresql al menos, usando
like any
seguido de la lista de expresiones regulares. Aquí hay un ejemplo, buscando identificar algunos antibióticos en una lista:fuente
También me preguntaba por algo así. Acabo de probar usando una combinación de
SUBSTRING
yIN
y es una solución efectiva para este tipo de problema. Pruebe la siguiente consulta:fuente
En Oracle puede usar una colección de la siguiente manera:
Aquí he usado un tipo de colección predefinido
ku$_vcnt
, pero puedes declarar el tuyo así:fuente
Para SQL Server, puede recurrir a Dynamic SQL.
La mayoría de las veces en tales situaciones tiene el parámetro de la cláusula IN basado en algunos datos de la base de datos.
El siguiente ejemplo es un poco "forzado", pero puede coincidir con varios casos reales encontrados en bases de datos heredadas.
Suponga que tiene una tabla de Personas donde los nombres de las personas se almacenan en un solo campo PersonName como FirstName + '' + LastName. Debe seleccionar todas las personas de una lista de nombres, almacenados en el campo NameToSelect en la tabla NamesToSelect , además de algunos criterios adicionales (como filtrado por género, fecha de nacimiento, etc.)
Puedes hacerlo de la siguiente manera
fuente
Puedo tener una solución para esto, aunque hasta donde sé, solo funcionará en SQL Server 2008. Descubrí que puedes usar el constructor de filas descrito en https://stackoverflow.com/a/7285095/894974 para unirte a una tabla 'ficticia' usando una cláusula like. Suena más complejo de lo que es, mira:
Esto dará como resultado que todos los usuarios tengan direcciones de correo electrónico como las que se proporcionan en la lista. Espero que sea de utilidad para cualquiera. El problema me había estado molestando por un tiempo.
fuente
A partir de 2016, SQL Server incluye una
STRING_SPLIT
función . Estoy usando SQL Server v17.4 y conseguí que esto funcione para mí:fuente
Si está utilizando MySQL, lo más cercano que puede obtener es la búsqueda de texto completo:
Búsqueda de texto completo, documentación de MySQL
fuente
Esto funciona para valores separados por comas
Evalúa a:
Si desea que use índices, debe omitir el primer
'%'
carácter.fuente
En Oracle RBDMS puede lograr este comportamiento usando REGEXP_LIKE función .
El siguiente código probará si la cadena tres está presente en la expresión de lista uno | dos | tres | cuatro | cinco (en el que el símbolo de tubería " | " significa operación lógica OR).
La expresión anterior es equivalente a:
Entonces tendrá éxito.
Por otro lado, la siguiente prueba fallará.
Hay varias funciones relacionadas con las expresiones regulares (REGEXP_ *) disponibles en Oracle desde la versión 10g. Si usted es un desarrollador de Oracle y le interesa este tema, este debería ser un buen comienzo Uso de expresiones regulares con la base de datos Oracle .
fuente
Puede ser que pienses la combinación como esta:
Si ha definido el índice de texto completo para su tabla de destino, entonces puede usar esta alternativa:
fuente
No hay respuesta como esta:
En Oracle no hay problema.
fuente
En Teradata puedes usar
LIKE ANY ('%ABC%','%PQR%','%XYZ%')
. A continuación se muestra un ejemplo que ha producido los mismos resultados para mí.fuente
Sé que es muy tarde, pero tuve una situación similar. Necesitaba un operador "Me gusta" para un conjunto de procedimientos almacenados que tengo, que aceptan muchos parámetros y luego los usa para agregar datos de múltiples sistemas RDBMS, por lo tanto, ningún truco específico de RDBMS funcionaría, sin embargo, el procedimiento almacenado y cualquier función se ejecutará en MS SQL Server, por lo que podemos usar T-SQL para la funcionalidad de generar las declaraciones SQL completas para cada RDBMS, pero la salida debe ser bastante independiente de RDBMS.
Esto es lo que se me ocurrió por el momento para convertir una cadena delimitada (como un parámetro que entra en un procedimiento almacenado) en un bloque de SQL. Lo llamo "Liquen" por "ME GUSTA". ¿Consíguelo?
Lichen.sql
La detección del delimitador posiblemente esté planificada, pero por ahora es un punto y coma por lo que puede ingresarla
default
allí. Probablemente hay errores en esto. los@leadingAnd
parámetro es solo un valor de bit para determinar si desea colocar un "Y" al frente del bloque para que encaje perfectamente con otras adiciones de la cláusula WHERE.Ejemplo de uso (con delimitador en argString)
Devuelve un nvarchar (512) que contiene:
También omitirá el bloque si la entrada no contiene un delimitador:
Ejemplo de uso (sin delimitador en argString)
Devuelve un nvarchar (512) que contiene:
Continuaré trabajando en esto, así que si he pasado por alto algo (evidentemente obvio o no), siéntanse libres de comentar o comunicarse.
fuente
hacer esto
o
fuente