Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Valores separados por vírgula na cláusula MySQL IN


Com base no exemplo FIND_IN_SET() de @Jeremy Smith, você pode fazer isso com uma junção para não precisar executar uma subconsulta.
SELECT * FROM table t
JOIN locations l ON FIND_IN_SET(t.e_ID, l.city) > 0
WHERE l.e_ID = ?

Isso é conhecido por ter um desempenho muito ruim, pois tem que fazer varreduras de tabela, avaliando a função FIND_IN_SET() para todos combinação de linhas em table e locations . Ele não pode usar um índice e não há como melhorá-lo.

Eu sei que você disse que está tentando tirar o melhor proveito de um design de banco de dados ruim, mas você deve entender o quão drasticamente ruim isso é.

Explicação:Suponha que eu lhe peça para procurar em uma lista telefônica todas as pessoas cuja inicial, do meio ou da última inicial seja "J". Não há como a ordem ordenada do livro ajudar neste caso, já que você precisa digitalizar cada página de qualquer maneira.

O LIKE solução dada por @fthiella tem um problema semelhante em relação ao desempenho. Não pode ser indexado.

Veja também minha resposta para O armazenamento de uma lista delimitada em uma coluna de banco de dados é tão ruim assim? para outras armadilhas dessa maneira de armazenar dados desnormalizados.

Se você puder criar uma tabela suplementar para armazenar um índice, poderá mapear os locais para cada entrada na lista de cidades:
CREATE TABLE location2city (
 location INT,
 city INT,
 PRIMARY KEY (location, city)
); 

Supondo que você tenha uma tabela de pesquisa para todas as cidades possíveis (não apenas as mencionadas na table ) você pode suportar a ineficiência uma vez para produzir o mapeamento:
INSERT INTO location2city (location, city)
  SELECT l.e_ID, c.e_ID FROM cities c JOIN locations l
  ON FIND_IN_SET(c.e_ID, l.city) > 0;

Agora você pode executar uma consulta muito mais eficiente para encontrar entradas em sua table :
SELECT * FROM location2city l
JOIN table t ON t.e_ID = l.city
WHERE l.e_ID = ?;

Isso pode fazer uso de um índice. Agora você só precisa tomar cuidado para que qualquer INSERT/UPDATE/DELETE de linhas em locations também insere as linhas de mapeamento correspondentes em location2city .