2

我有一个包含 product_name 字段的表。然后是另一个带有模型的表。

===products
product_id, product_name

===models
model_id, model_name

我正在寻找一种方法来执行以下操作。

  1. 型号名称可以包含用连字符分隔的单词,即 JVC-600-BLACK
  2. 对于每个模型,我需要检查产品名称中模型的每个单词是否存在。

我需要一些结果,如下所示。

== results
model_id, product_id

如果有人能指出我正确的方向,那将是一个很大的帮助。

笔记

  1. 这些是包含数百万条记录的巨大表,model_name 中的单词数不固定。
  2. 模型中的单词可以以任何顺序存在或介于两者之间或产品名称中的其他单词
4

3 回答 3

1

我不知道这个解决方案是否更快,让您检查您是否关心:

--=======================
-- 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
于 2013-08-22T12:27:32.733 回答
1

这是一个函数,它使用分隔符将第一个字符串拆分为-多个部分,并在第二个字符串中查找每个部分,1如果找到所有部分,则返回,0否则返回。

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

您可以将上述功能用于您的问题,如下所示:

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

它不会很快,但我认为不存在快速解决方案,因为您的问题不允许索引。可能可以更改数据库结构以实现这一点,但具体如何做到这一点在很大程度上取决于您的数据是什么样的。

于 2013-08-22T09:47:35.343 回答
0

您可能需要考虑使用 SQL Server 的全文搜索功能。简而言之,它会在设置时指定的表和列中对所有单词进行编目(默认情况下忽略“and”、“or”、“a”和“the”等干扰词,但此干扰世界列表是可配置的)全文目录并提供一些功能,使您可以利用该目录快速查找行。

于 2013-08-22T12:52:47.807 回答