Question

Puis-je/dois-je utiliser un critère LIKE dans le cadre d'une INNER JOIN lors de la création d'une procédure stockée/requête ?Je ne suis pas sûr de demander la bonne chose, alors laissez-moi vous expliquer.

Je crée une procédure qui va prendre une liste de mots-clés à rechercher dans une colonne contenant du texte.Si j'étais assis devant la console, je l'exécuterais comme tel :

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

Mais une astuce que j'ai découverte il y a peu pour effectuer une analyse de liste "fortement typée" dans une procédure stockée consiste à analyser la liste en une variable de table/table temporaire, en la convertissant dans le type approprié, puis en effectuant une INNER JOIN sur cette table. dans mon jeu de résultats final.Cela fonctionne très bien lors de l'envoi, par exemple, d'une liste d'identifiants entiers à la procédure.Je finis par avoir une dernière requête qui ressemble à ceci :

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

Je veux utiliser cette astuce avec une liste de chaînes.Mais comme je recherche un mot-clé particulier, je vais utiliser la clause LIKE.Donc, idéalement, je pense que ma requête finale ressemblerait à ceci :

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

Est-ce possible/recommandé ?

Existe-t-il une meilleure façon de faire quelque chose comme ça ?


La raison pour laquelle je mets des caractères génériques aux deux extrémités de la clause est qu'il existe des termes « archdémon », « bête-guerrier », « dégâts directs » et « dégâts de combat » qui sont utilisés dans les textes des cartes.

J'ai l'impression qu'en fonction des performances, je peux soit utiliser la requête que j'ai spécifiée, soit utiliser une recherche par mot-clé en texte intégral pour accomplir la même tâche ?

À part demander au serveur d'effectuer un index de texte sur les champs dans lesquels je souhaite effectuer une recherche de texte, dois-je faire autre chose ?

Était-ce utile?

La solution

Votre première requête fonctionnera mais nécessitera une analyse complète de la table car tout index sur cette colonne sera ignoré.Vous devrez également faire du SQL dynamique pour générer toutes vos clauses LIKE.

Essayez une recherche en texte intégral si vous utilisez SQL Server ou consultez l'un des Lucène mises en œuvre.Joel a parlé de son succès récemment.

Autres conseils

Essaye ça

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

Cette pratique n'est pas idéale.Utiliser avec précaution.

Il semble que vous recherchiez une recherche en texte intégral.Parce que vous souhaitez interroger un ensemble de mots-clés par rapport à la description de la carte et trouver des résultats ?Correct?

Personnellement, je l'ai déjà fait et cela a bien fonctionné pour moi.Les seuls problèmes que j'ai pu voir sont peut-être des problèmes avec une colonne non indexée, mais je pense que vous auriez le même problème avec une clause Where.

Mon conseil est simplement de regarder les plans d’exécution entre les deux.Je suis sûr que le meilleur sera différent selon la situation, comme tous les bons problèmes de programmation.

@Dillie-O
Quelle est la taille de ce tableau ?
Quel est le type de données du champ Description ?

Si l’un ou l’autre est petit, une recherche en texte intégral sera excessive.

@Dillie-O
Ce n'est peut-être pas la réponse que vous cherchiez, mais je préconiserais un changement de schéma...

schéma proposé :

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)

Cela vous permettra d'utiliser des index sans avoir à implémenter une solution complémentaire et de conserver vos données atomiques.

en rapport: Conception de base de données SQL recommandée pour les balises ou le balisage

Une astuce que j'ai ramassée un peu pour faire l'analyse de la liste "fortement tapée" dans une procédure stockée consiste à analyser la liste dans une variable de table / Tableau temporaire

Je pense que ce à quoi vous pourriez faire allusion ici, c'est de mettre les mots-clés à inclure dans un tableau, puis d'utiliser division relationnelle pour trouver des correspondances (on pourrait également utiliser un autre tableau pour les mots à exclure).Pour un exemple concret en SQL, voir Recherches par mots-clés par Joe Celko.

essayez-le...

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

Ça marche pour moi. :-)

Les performances dépendront du serveur réel que vous utilisez, du schéma des données et de la quantité de données.Avec les versions actuelles de MS SQL Server, cette requête devrait s'exécuter correctement (MS SQL Server 7.0 avait des problèmes avec cette syntaxe, mais cela a été résolu dans le SP2).

Avez-vous exécuté ce code via un profileur ?Si les performances sont suffisamment rapides et que les données disposent des index appropriés, vous devriez être prêt.

LIKE '%fiend%' n'utilisera jamais de recherche, LIKE 'fiend%' le fera.Une simple recherche par caractère générique n'est pas exploitable

Essaye ça;

SELECT Id, Name, Description
FROM dbo.Card
INNER JOIN @tblKeyword ON dbo.Card.Description LIKE '%' + 
                                CONCAT(CONCAT('%',@tblKeyword.Value),'%') + '%'
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top