Pergunta

Posso/devo usar critérios LIKE como parte de um INNER JOIN ao criar um procedimento/consulta armazenado?Não tenho certeza se estou perguntando a coisa certa, então deixe-me explicar.

Estou criando um procedimento que vai pegar uma lista de palavras-chave a serem pesquisadas em uma coluna que contém texto.Se eu estivesse sentado no console, executaria assim:

SELECT Id, Name, Description
  FROM dbo.Card
 WHERE Description LIKE '%warrior%' 
       OR
       Description LIKE '%fiend%' 
       OR 
       Description LIKE '%damage%'

Mas um truque que aprendi há pouco para fazer a análise de lista "fortemente digitada" em um procedimento armazenado é analisar a lista em uma variável de tabela/tabela temporária, convertendo-a para o tipo adequado e, em seguida, fazendo um INNER JOIN nessa tabela no meu conjunto de resultados finais.Isso funciona muito bem ao enviar, digamos, uma lista de IDs inteiros para o procedimento.Acabo tendo uma consulta final parecida com esta:

SELECT Id, Name, Description
  FROM dbo.Card
       INNER JOIN @tblExclusiveCard ON dbo.Card.Id = @tblExclusiveCard.CardId

Quero usar esse truque com uma lista de strings.Mas como estou procurando uma palavra-chave específica, usarei a cláusula LIKE.Então, idealmente, estou pensando que minha consulta final seria assim:

SELECT Id, Name, Description
  FROM dbo.Card
       INNER JOIN @tblKeyword ON dbo.Card.Description LIKE '%' + @tblKeyword.Value + '%'

Isso é possível/recomendado?

Existe uma maneira melhor de fazer algo assim?


A razão pela qual estou colocando curingas em ambas as extremidades da cláusula é porque existem termos “arquidemônio”, “fera-guerreira”, “dano direto” e “dano de batalha” que são usados ​​nos textos das cartas.

Estou tendo a impressão de que, dependendo do desempenho, posso usar a consulta especificada ou uma pesquisa por palavra-chave de texto completo para realizar a mesma tarefa.

Além de fazer com que o servidor faça um índice de texto nos campos que desejo pesquisar, há mais alguma coisa que preciso fazer?

Foi útil?

Solução

Sua primeira consulta funcionará, mas exigirá uma verificação completa da tabela porque qualquer índice nessa coluna será ignorado.Você também terá que fazer SQL dinâmico para gerar todas as suas cláusulas LIKE.

Tente uma pesquisa de texto completo se você estiver usando o SQL Server ou confira um dos Lucena implementações.Joel falou sobre seu sucesso recentemente.

Outras dicas

Experimente isso

    select * from Table_1 a
    left join Table_2 b on b.type LIKE '%' + a.type + '%'

Esta prática não é ideal.Use com cuidado.

Parece que você está procurando uma pesquisa de texto completo.Porque você deseja consultar um conjunto de palavras-chave na descrição do cartão e encontrar algum resultado?Correto?

Pessoalmente, já fiz isso antes e funcionou bem para mim.Os únicos problemas que pude ver são possivelmente problemas com uma coluna não indexada, mas acho que você teria o mesmo problema com uma cláusula where.

Meu conselho para você é apenas observar os planos de execução entre os dois.Tenho certeza de que será diferente qual é o melhor dependendo da situação, assim como todos os bons problemas de programação.

@Dillie-O
Qual o tamanho desta mesa?
Qual é o tipo de dados do campo Descrição?

Se um deles for pequeno, uma pesquisa de texto completo será um exagero.

@Dillie-O
Talvez não seja a resposta que você procura, mas eu defenderia uma mudança de esquema ...

esquema proposto:

create table name(
    nameID identity / int
   ,name varchar(50))

create table description(
    descID identity / int
   ,desc varchar(50)) --something reasonable and to make the most of it alwase lower case your values

create table nameDescJunc(
    nameID  int
    ,descID int)

Isso permitirá que você use índices sem precisar implementar uma solução complementar e manterá seus dados atômicos.

relacionado: Design de banco de dados SQL recomendado para tags ou marcação

Um truque que eu peguei um pouco para fazer a lista de "digitados fortemente" analisando em um procedimento armazenado é analisar a lista em uma tabela/tabela temporária de tabela

Acho que você está se referindo aqui a colocar as palavras-chave a serem incluídas em uma tabela e depois usar divisão relacional para encontrar correspondências (também pode usar outra tabela para palavras a serem excluídas).Para um exemplo prático em SQL, consulte Pesquisas de palavras-chave por Joe Celko.

tente...

select * from table11 a inner join  table2 b on b.id like (select '%'+a.id+'%') where a.city='abc'.

Funciona para mim.:-)

O desempenho dependerá do servidor real que você usa, do esquema dos dados e da quantidade de dados.Com as versões atuais do MS SQL Server, essa consulta deve funcionar perfeitamente (o MS SQL Server 7.0 teve problemas com essa sintaxe, mas foi abordado no SP2).

Você executou esse código por meio de um criador de perfil?Se o desempenho for rápido o suficiente e os dados tiverem os índices apropriados, você estará pronto.

LIKE '%fiend%' nunca usará uma busca, LIKE 'fiend%' usará.Simplesmente uma pesquisa curinga não é sargável

Experimente isto;

SELECT Id, Name, Description
FROM dbo.Card
INNER JOIN @tblKeyword ON dbo.Card.Description LIKE '%' + 
                                CONCAT(CONCAT('%',@tblKeyword.Value),'%') + '%'
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top