2009-10-24 73 views
3

我有一个表与特定的列,其中有一列包含逗号分隔值如测试,考试,结果,其他如何比较逗号分隔值的两列值?

我会传递一个字符串,如结果,样本,未知,额外作为存储过程的参数。然后我想通过检查此字符串中的每个短语来获取相关记录。

例如:

表A

ID  Name    Words 
1   samson    test,exam,result,other 
2   john    sample,no query 
3   smith    tester,SE 

现在我想搜索结果,样品,未知的,群众演员

那么结果应该是

ID  Name    Words 
1   samson    test,exam,result,other 
2   john    sample,no query 

因为在第一个记录结果匹配和在第二个记录样本匹配。

+1

你用什么sql引擎? – 2009-10-24 16:14:18

+5

我会考虑修复我的数据库设计。 – Joe 2009-10-24 17:07:46

+0

你如何要求那些有'测试,考试,结果,其他'的人作为一组结果?这是一个次优设计。 – 2009-10-24 23:09:17

回答

1

我个人认为你会想看看你的应用程序/架构,仔细想想你是否真的想在数据库或应用程序中这样做。如果它不合适或不是一个选项,那么你需要创建一个自定义函数。这里的文章中的代码应该很容易修改,做你想做什么:

Quick T-Sql to parse a delimited string(也期待在评论的代码)

7

这不是一个伟大的设计,你知道的。更好地将单词分成单独的表格(ID,单词)。

也就是说,这应该做的伎俩:

set nocount on 
declare @words varchar(max) = 'result,sample,unknown,extras' 

declare @split table (word varchar(64)) 
declare @word varchar(64), @start int, @end int, @stop int 

-- string split in 8 lines 
select @words += ',', @start = 1, @stop = len(@words)+1 
while @start < @stop begin 
    select 
    @end = charindex(',',@words,@start) 
    , @word = rtrim(ltrim(substring(@words,@start,@[email protected]))) 
    , @start = @end+1 
    insert @split values (@word) 
end 

select * from TableA a 
where exists (
    select * from @split w 
    where charindex(','+w.word+',',','+a.words+',') > 0 
) 

我可以在DBA地狱燃烧提供你这个!

编辑:替换馅料w/SUBSTRING切片,长列表上快一个数量级。

+0

考虑点燃篝火下的火炬,彼得...... D – 2009-10-24 23:07:45

+1

嘿。我认为这是很好的你发布这个 - 作为一个很好的例子说明为什么不应该这样设计的东西。 – SquareCog 2009-10-24 23:14:53

+2

我同意设计可以正确完成,但不幸的是,我们中的一些人可能会遇到这类问题,并且没有能够改变某人的不良设计的奢侈品。感谢您发布这个! :) – Ryan 2014-01-02 22:41:05

0

就像其他人已经说过的 - 你有什么不好的设计。考虑使用适当的关系来表示这些事情。

话虽这么说,这里是如何做到这一点使用SQL Server的一个详细的文章: http://www.sommarskog.se/arrays-in-sql-2005.html

有一件事至今还没有一个已覆盖,因为它往往是一个非常糟糕的主意 - 但是,你是已经在处理一个坏主意,有时候两个错误是正确的 - 就是提取与任何字符串匹配的所有行(使用LIKE或其他类型),然后在客户端自己完成交集。如果你的字符串非常罕见并且高度相关,这可能工作得很好;在大多数情况下,这将是非常糟糕的。