Como executo uma pesquisa SQL simples de uma instrução em tabelas?
Pergunta
Suponha que existam duas tabelas: users
e groups
.
Como fornecer uma "pesquisa simples" na qual um usuário insere texto e os resultados contêm usuários e grupos cujos nomes contêm o texto?
O resultado da pesquisa deve distinguir entre os dois tipos.
Solução
O truque é combinar um UNION
com uma string literal para determinar o tipo de 'objeto' retornado.Na maioria dos (?) casos, UNION ALL será mais eficiente e deverá ser usado, a menos que sejam necessárias duplicatas nas subconsultas.O seguinte padrão deve ser suficiente:
SELECT "group" type, name
FROM groups
WHERE name LIKE "%$text%"
UNION ALL
SELECT "user" type, name
FROM users
WHERE name LIKE "%$text%"
OBSERVAÇÃO:Eu mesmo adicionei a resposta, porque me deparei com esse problema ontem, não consegui encontrar uma boa solução e usei esse método.Se alguém tiver uma abordagem melhor, sinta-se à vontade para adicioná-la.
Outras dicas
Se você usar "UNION ALL", o banco de dados não tentará remover duplicatas - você não terá duplicatas entre as duas consultas (já que a primeira coluna é diferente), então UNION ALL será mais rápido.
(Presumo que você não tenha duplicatas dentro de cada consulta que deseja remover)
Usar LIKE causará vários problemas, pois exigirá uma varredura de tabela sempre que o comparador LIKE começar com%.Isso força o SQL a verificar cada linha e trabalhar, byte por byte, através da string que você está usando para comparação.Embora isso possa ser bom quando você inicia, causa rapidamente problemas de dimensionamento.
A melhor maneira de lidar com isso é usar a pesquisa de texto completo.Embora esta seja uma opção mais complexa, ela fornecerá melhores resultados para bancos de dados muito grandes.Então você pode usar uma versão funcional do exemplo que Bobby Jack lhe deu para UNION ALL
seus dois conjuntos de resultados juntos e exibir os resultados.
Eu sugeriria outra adição
SELECT "group" type, name
FROM groups
WHERE UPPER(name) LIKE UPPER("%$text%")
UNION ALL
SELECT "user" type, name
FROM users
WHERE UPPER(name) LIKE UPPER("%$text%")
Você pode converter $text em maiúsculas primeiro ou apenas fazer isso na consulta.Dessa forma, você obtém uma pesquisa que não diferencia maiúsculas de minúsculas.