将两个关键字列表列与另一列匹配以进行匹配

时间:2010-08-12 18:35:06

标签: c# sql sql-server-2008

我正在使用.NET 4.0& C#和SQL Server 2008.我有一个表格产品,其中包含一个名为关键字的列。我有另外一个表有两列的兴趣接受拒绝。所有3列都包含以逗号分隔的关键字。我需要匹配:

  1. 如果接受&拒绝为空,然后有匹配
  2. 如果Accept有关键字,那么Accept&之间应该至少有1个关键字匹配关键字
  3. 如果Reject有关键字,则Reject&之间不应该匹配。关键字
  4. 2&组合3
  5. 理想情况下,我想在SQL查询中执行此操作。我对该命令的Managed或T-SQL存储过程持开放态度。


    好的,根据评论,我添加了这些表格:

    Keywords_Products [id(FK to Products),关键字]
    Keywords_Accepted [id(FK to User),关键字]
    Keywords_Rejected [id(FK to User),Keyword]

    因此,基于上述4条规则,我需要一组给定userId的产品。

4 个答案:

答案 0 :(得分:2)

真正的问题是关键字列表在一个字段中。打破以逗号分隔的列表并不是SQL的目的。

这些实际应该在1对多的表中(ProductKeywords,AcceptInterest,RejectInterests)。

答案 1 :(得分:2)

我建议您根据我的有限信息重新构建您的数据库:

Product
---------
ProductId - int
ProductName - varchar
Accepted - bit

ProductKeywords
---------------
KeywordId - int
ProductId - int
Keyword - varchar

我对你的数据结构有点困惑。这个模型适合你吗?如果是这样,它将来会阻止很多可维护性和性能问题。

答案 2 :(得分:1)

以逗号分隔的字符串的一个选项:

  • 表值函数(以逗号分隔的字符串作为输入并返回表的函数)

将“Accept”表值函数的结果加入“关键字”表值函数的结果中,如果返回行,则表示您有匹配。

第二个选项是创建一个函数,将Word n拉出一个字段,然后对第二个字段执行CHARINDEX()等。将它放在WHILE循环中,一旦CHARINDEX()返回大于零,退出循环。

答案 3 :(得分:0)

如果你按原样坚持桌面结构(我怀疑你是这样),那么你可能最好将其分成多个部分。您的第一部分是创建一个可以根据分隔符拆分字符串的函数。如何做到这一点已经在another question得到了很好的回答。

如果您通过创建一个特定于Products表上的Keywords字段的分割函数来创建细分,也会有所帮助。您可以传递ProductId并让它返回该ProductId的关键字的东西。

从那里,您可以选择与给定产品匹配的兴趣

SELECT * FROM Interests i
WHERE 
    (i.Accept = '' AND i.Reject = '')
    OR
    (
        EXISTS (SELECT * FROM Split(',', i.Accept) ia WHERE ia.[Value] IN (ProductKeywords(@ProductId)))
        AND
        NOT EXISTS (SELECT * FROM Split(',', i.Reject) ir WHERE ir.[Value] IN (ProductKeywords(@ProductId)))
    )