2 votes

Vérification de l'existence de tous les mots d'une colonne du tableau 1 dans une autre colonne du tableau 2

J'ai une table qui contient le champ product_name. Puis une autre table avec des modèles.

===products
product_id, product_name

===models
model_id, model_name

Je cherche un moyen de faire ce qui suit.

  1. Les noms de modèles peuvent comporter des mots séparés par un trait d'union, par exemple JVC-600-BLACK.
  2. Pour chaque modèle, je dois vérifier l'existence de chaque mot du modèle dans le nom du produit.

J'aurai besoin du résultat à un endroit comme ci-dessous.

== results
model_id, product_id

Si quelqu'un peut m'indiquer la bonne direction, cela m'aiderait beaucoup.

Notes

  1. Il s'agit d'énormes tables contenant des millions d'enregistrements et un certain nombre d'informations. de mots dans le nom du modèle n'est pas fixe.
  2. les mots du modèle peuvent exister dans n'importe quel ordre ou entre les mots du nom du produit

1voto

Dukeling Points 31203

Voici une fonction qui divise la première chaîne en plusieurs parties à l'aide de - comme délimiteur et recherche chaque partie de la deuxième chaîne, en renvoyant 1 si toutes les pièces ont été trouvées et 0 autrement.

CREATE FUNCTION dbo.func(@str1 varchar(max), @str2 varchar(max))
RETURNS BIT
AS
BEGIN
  DECLARE @pos INT, @newPos INT,
          @delimiter NCHAR(1)
  SET @delimiter = '-'
  SET @pos = 1
  SET @newPos = 0

  WHILE (@newPos < LEN(@str1))
  BEGIN
    SET @newPos = CHARINDEX(@delimiter, @str1, @pos)
    IF @newPos = 0
      SET @newPos = LEN(@str1)+1
    DECLARE @data2 NVARCHAR(MAX)
    SET @data2 = SUBSTRING(@str1, @pos, @newPos-@pos)

    IF CHARINDEX(@data2, @str2) = 0
      RETURN 0

    SET @pos = @newPos + 1
    IF @newPos = 0
      BREAK
  END
  RETURN 1
END

Vous pouvez utiliser la fonction ci-dessus pour résoudre votre problème de la manière suivante :

SELECT model_id, product_id
FROM models
JOIN products 
  ON dbo.func(models.model_name, products.product_name) = 1

Ce ne sera pas rapide, mais je ne pense pas qu'une solution rapide existe, puisque votre problème ne permet pas l'indexation. Il peut être possible de modifier la structure de la base de données pour le permettre, mais la façon dont cela peut être fait dépend en grande partie de la nature de vos données.

1voto

Alexey Points 839

Je ne sais pas si cette solution est plus rapide, à vous de vérifier si cela vous intéresse :

--=======================
-- sample data
-- ======================
declare @Products table
(
    product_id int,
    product_name nvarchar(max)
)

insert into @Products select 1, 'sdfsd def1 abc1klm1 sdljkfd'
insert into @Products select 2, 'sdfsd def2 abc2klm2 sdljkfd'
insert into @Products select 3, 'sdfsd def3 abc3klm3 sdljkfd'

declare @Models table
(
    model_id int,
    model_name nvarchar(max)
)

insert into @Models select 1, 'abc1-def1-klm1'
insert into @Models select 2, 'abc2-def2-klm2'
insert into @Models select 3, 'abc3-def3-klm3'

--=======================
-- solution
-- ======================
select t1.product_id, t2.model_id from @Products t1
cross join (
select 
    t1.model_id, Word = t2.r.value('.', 'nvarchar(max)') 
from (select model_id, x = cast('<e>' + replace(model_name, '-', '</e><e>') + '</e>' as xml) from @Models ) t1
cross apply x.nodes('e') as t2 (r)
) t2
group by product_id, model_id
having min(charindex(word, product_name)) != 0

0voto

Ray Saltrelli Points 1455

Vous pouvez envisager d'utiliser la fonction Recherche en texte intégral de SQL Server. En bref, elle catalogue tous les mots (en ignorant les mots parasites tels que "et", "ou", "a" et "le" par défaut, mais cette liste de mots parasites est configurable) dans les tables et les colonnes que vous spécifiez lors de la configuration du catalogue de texte intégral et offre une poignée de fonctions qui vous permettent d'utiliser ce catalogue pour trouver rapidement des lignes.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X