Noob de SQL que intenta devolver resultados de db si se encuentra un valor de tabla en una matriz. Estoy usando Node JS y Postgres.
Hasta ahora, puedo descubrir cómo devolver el resultado de un solo elemento:
SELECT * FROM table WHERE position(value in 'someval1')>0 // returns [{ id: 1, value: 'val1' }]No sé cómo reemplazar el único elemento anterior ('someval1') con una matriz.
EJEMPLO
Dada la siguiente tabla:
| identificación | valor |
|---|---|
| 1 | val1 |
| 2 | val2 |
| 3 | val3 |
y la matriz: ['foo', 'someval1', 'anotherval2', 'bar']
¿Cómo puedo verificar que el "valor" de la tabla existe dentro de cada elemento de la matriz para devolver?
[ { id: 1, value: 'val1' }, { id: 2, value: 'val2' } ]Esto es al revés. Normalmente harías algo como...
select * from theTable where searchField like '%text1%' or searchField like '%text2%'Pero parece que está tratando de extraer filas de una tabla cuando los datos de la fila están contenidos en cualquiera de varios valores en la matriz de criterios. Lo que creo que podría estar buscando son tablas temporales (aunque esta sintaxis exacta podría quedar obsoleta pronto y no veo el reemplazo en este momento). Crearía la tabla temporal con solo un campo con sus valores de texto de la matriz que contiene. Luego, puede usar la combinación de tablas para obtener el comportamiento que está buscando. Algo como...
select dt.*, tt.SearchString from DataTable dt right join TempTable tt on tt.SearchString like '%'+dt.value+'%'Y no lo pasé por un probador de ningún tipo, pero con la unión correcta, solo debería incluir filas que coincidan en la tabla temporal. Suponiendo que mi código tiene errores tipográficos, busque en las tablas temporales (o alternativas) y luego únase a .
Editar: pensé que ofrecería un poco más en las tablas temporales ya que mencionó que es nuevo en SQL. Creo que querrías un código como...
create temporary table TempTable (searchString varchar(100)); insert into TempTable values ('foo'), ('someval1'), ('anotherval2'), ('bar');Y, por supuesto, está ejecutando eso antes de hacer la unión con la tabla real.
De acuerdo, pensé en una ligera variación del enfoque que puede usar si las tablas temporales no son una opción (por eso estoy haciendo de esta una respuesta separada en caso de que sea la que termine funcionando para usted).
Cree una tabla normal que use específicamente con el propósito de contener los valores de la matriz. Si varios usuarios pueden estar ejecutando este proceso al mismo tiempo, necesitará una identificación (identificación de sesión, identificación de usuario, algo confiablemente único) para asegurarse de que solo está usando los valores relevantes para esa persona. Entonces, querrías una mesa como...
create table SearchTerms (ID int not null AUTO_INCREMENT, sessionID varchar(25), searchTerm varchar(50));Luego, cuando ejecuta sus consultas, comienza con inserciones para cargar los términos...
insert into SearchTerms values ('0129205017_smith', 'foo'), ('0129205017_smith', 'someval1'), ('0129205017_smith', 'anotherval2'), ('0129205017_smith', 'bar');A continuación, ejecuta su consulta real que se parece a...
select dt.*, st.searchTerm from SearchTerms st left join DataTable dt on st.searchTerm like '%'+dt.value+'%' where st.sessionID = '0129205017_smith';Y luego es posible que desee hacer una limpieza para que la tabla de términos de búsqueda no se sature con cosas...
delete from SearchTerms where sessionID = '0129205017_smith';Podría considerar usar expresiones regulares. Es un poco menos eficaz que LIKE, pero a menos que su conjunto de datos realmente necesite mucha optimización, probablemente nunca lo notará. También he incluido una alternativa que usa una unión a una lista de valores y ME GUSTA para producir los mismos resultados. Mira este violín. Configuré la versión en postgres 14, ya que no especificaste:
https://dbfiddle.uk/?rdbms=postgres_14&fiddle=7062f6828a161c934c3e8ef96110dd05
CREAR e INSERTAR:
create table SearchTerms (ID serial primary key, sessionID varchar(25), searchTerm varchar(50)); insert into SearchTerms (sessionID, searchTerm) values ('0129205017_smith', 'foo'), ('0129205017_smith', 'someval1'), ('0129205017_smith', 'anotherval2'), ('0129205017_smith', 'bar');Solución usando expresiones regulares (~):
select * from searchTerms where searchTerm ~ 'val1|val2';Solución usando LIKE y una unión a una lista de valores:
select * from searchTerms s join (SELECT 'val1' as term UNION ALL SELECT 'val2' as term) v on s.searchTerm like concat('%', v.term, '%');Personalmente, prefiero las expresiones regulares a Me gusta por su flexibilidad y concisión, y muy rara vez encuentro una situación en la que el uso de LIKE ofrezca suficientes mejoras de rendimiento para usarlas a favor de las expresiones regulares.