Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/261.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将两个关键字列表列与另一列进行匹配_C#_Sql_Sql Server 2008 - Fatal编程技术网

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

C# 将两个关键字列表列与另一列进行匹配,c#,sql,sql-server-2008,C#,Sql,Sql Server 2008,我正在使用.NET4.0&C和SQLServer2008。我有一个表Products,其中有一列名为Keywords。我还有一个表,有两列接受和拒绝。所有3列都包含用逗号分隔的关键字。我需要匹配: 如果接受和拒绝为空,则存在匹配项 如果Accept有关键字,则Accept和关键字之间至少应有1个关键字匹配 如果拒绝包含关键字,则拒绝和关键字之间不应存在匹配 2和3的组合 理想情况下,我希望在SQL查询中执行此操作。我对以这种顺序管理或T-SQL的存储过程持开放态度 好的,根据评论,我添加了以下表

我正在使用.NET4.0&C和SQLServer2008。我有一个表Products,其中有一列名为Keywords。我还有一个表,有两列接受和拒绝。所有3列都包含用逗号分隔的关键字。我需要匹配:

如果接受和拒绝为空,则存在匹配项 如果Accept有关键字,则Accept和关键字之间至少应有1个关键字匹配 如果拒绝包含关键字,则拒绝和关键字之间不应存在匹配 2和3的组合 理想情况下,我希望在SQL查询中执行此操作。我对以这种顺序管理或T-SQL的存储过程持开放态度

好的,根据评论,我添加了以下表格:

关键词\产品[id FK到产品,关键词] 关键词\已接受[id FK给用户,关键词] 关键字\u已拒绝[id FK给用户,关键字]


因此,根据上述4条规则,我需要一组针对给定用户ID的产品。

真正的问题是关键字列表位于一个字段中。分解逗号分隔的列表并不是SQL设计的真正目的


这些实际上应该在1对多的表ProductKeywords、AcceptInterest、RejectInterest中。

真正的问题是关键字列表位于一个字段中。分解逗号分隔的列表并不是SQL设计的真正目的


实际上,这些应该在1对多的表ProductKeywords、AcceptInterest、RejectInterest中。

我建议您根据我掌握的有限信息,按照以下方式重新构建数据库:

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

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

不过,我对您的数据结构有点困惑。这个模型适合你吗?如果是这样的话,它将在将来避免许多维护性和性能方面的麻烦。

我建议您根据我掌握的有限信息,按照以下方式重组数据库:

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

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

不过,我对您的数据结构有点困惑。这个模型适合你吗?如果是这样的话,它将在将来避免许多维护性和性能方面的麻烦。

如果您仍然坚持使用表结构,我怀疑您是这样的,那么您最好将其分解为多个部分。第一步是创建一个可以基于分隔符拆分字符串的函数。如何做到这一点,在中国已经得到了很好的回答

如果您通过创建一个特定于Products表上的Keywords字段的函数来对split函数进行细化,这也会有所帮助。您可以传入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)))
    )

如果您仍然坚持使用表结构,我怀疑您是这样,那么您最好将其分解为多个部分。第一步是创建一个可以基于分隔符拆分字符串的函数。如何做到这一点,在中国已经得到了很好的回答

如果您通过创建一个特定于Products表上的Keywords字段的函数来对split函数进行细化,这也会有所帮助。您可以传入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)))
    )

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

Table value函数一个函数,它以逗号分隔的字符串作为输入,并返回一个表 将Accept table value函数的结果与Keywords table value函数的结果连接起来,如果返回了行,就知道有匹配项


第二种选择是创建一个函数,从一个字段中提取单词n,然后对第二个字段执行CHARINDEX等操作。将其放入WHILE循环中,一旦获得大于零的CHARINDEX返回值,就退出循环。

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

Table value函数一个函数,它以逗号分隔的字符串作为输入,并返回一个表 将Accept table value函数的结果与Keywords table value函数的结果连接起来,如果返回了行,就知道有匹配项


第二种选择是创建一个函数,从一个字段中提取单词n,然后对第二个字段执行CHARINDEX等操作。将其放入WHILE循环,一旦您得到大于零的CHARINDEX返回值,就退出循环。

不是答案,而是建议,因此我将作为评论发布。如果您的关键字被规范化到另一个具有多对多关系的表中,这会容易得多。是的,这种数据库设计听起来像是糟糕的魔咒。这是可以做到的,但确实很痛苦。它也将是缓慢的,因为你不能索引的关键字字段。顺便说一句,它打破了1NF根据每个人的建议添加的表格。添加到问题中。不是答案,而是建议,所以我会发表评论。如果将关键字规范化到另一个带有
多对多关系。是的,这个数据库设计听起来很糟糕。这是可以做到的,但确实很痛苦。它也将是缓慢的,因为你不能索引的关键字字段。顺便说一句,它打破了1NF根据每个人的建议添加的表格。顺便说一句,其他人建议的更规范化的表格方法或多或少也是一个好主意。顺便说一句,其他人建议的更规范化的表方法或多或少也是一个好主意。我只是想补充一下。我刚才想到的一个改进是,如果这是在一个进程中,你可以分配结果ProductKeywords@ProductId设置为表变量,以便在选择过程中只调用一次函数。执行计划可能会为您优化这一点,但如果您能够管理它,那么预测它并没有坏处ProductKeywords@ProductId设置为表变量,以便在选择过程中只调用一次函数。执行计划可能会为您优化这一点,但如果您能够管理它,预测也不会有什么坏处。