Eu tenho uma tabela de banco de dados MySQL que faz referência a diferentes palavras e suas localizações em documentos. Desejo retornar os IDs dos documentos que contêm todas as palavras.
Aqui está uma tabela de exemplo.
docid wordid
1 4
2 4
1 2
1 5
Ok, agora diga que alguém consultou o banco de dados para as palavras que tinham WORDIDs 4, 2 e 5.
Minha instrução SQL SELECT errônea seria algo como:
Select docid from table where wordid = 4 and wordid = 2 and wordid = 5
Isso está me dando 0 resultados.
Eu vi em outros lugares onde a where in
cláusula foi sugerida:
Se bem entendi, esta é outra maneira de escrever uma cláusula OR. Eu tentei isso:
select docid from table where wordid in (4,2,5)
Mas, isso está me dando todos os resultados. Deve excluir docid 2, pois não contém as outras palavras. Estou esperando apenas obter docid 1.
No entanto, eu poderia estar usando a where in
cláusula incorretamente, pois tenho muito pouca experiência em banco de dados.
Como posso retornar docids que contêm todas as palavras?
Observe também que minha cláusula where será gerada dinamicamente em um loop FOR. A consulta pode ser tão simples quanto uma ou duas palavras, ou pode ter 10 ou 12 palavras. Estou procurando uma estrutura de consulta que leve em consideração a velocidade. Por favor, deixe-me saber se você precisar de mais informações.
Para referência, estou tentando converter este código em PHP/MYSQL, mas não entendo a instrução sql aqui ou seu equivalente em MYSQL:
Este é o problema da divisão relacional e há uma pergunta sobre isso no SO, com várias maneiras de escrever essa consulta, além de análise de desempenho para o PostgreSQL: Como filtrar resultados de SQL em uma relação tem-muitos-através
Copiando descaradamente o formulário de código e removendo/alterando o código para respostas que não possuem recursos do MySQL, como CTEs,
EXCEPT
,INTERSECT
etc., aqui estão algumas maneiras de fazer isso.Suposições:
factors
UNIQUE
restrição(wordid, docid)
documents
e umawords
tabela:Fácil de escrever, eficiência média:
Fácil de escrever, eficiência média:
Mais complexo de escrever, eficiência muito boa no Postgres - provavelmente ruim no MySQL:
Mais complexo de escrever, eficiência muito boa no Postgres - e provavelmente o mesmo no MySQL:
Mais complexo de escrever, eficiência muito boa no Postgres - e provavelmente o mesmo no MySQL:
Fácil de escrever e estender para um conjunto arbitrário,
words
mas não tão eficiente quanto as soluçõesJOIN
eEXISTS
:Fácil de escrever, não é boa eficiência:
Aproveite para testá-los :)