2012-04-03 60 views
1

我有一个这样的搜索字符串:“值1,值4,value8”搜索分隔字符串列

我有一个数据库表的条目是这样的:

id | value 
-----+------------------------ 
1 | value1,value2,value3 
2 | value3,value4,value9 
3 | value4,value8,value9 
4 | value2,value3,value9 

现在我寻找一种方法来从包含值1,值4或value8数据库中搜索所有记录。

在这个例子中,我想记录的1,2和3的时候我做了选择。

我已经有一个拆分功能,将我的搜索字符串拆分为IN VALUES,如下所示:'value1','value4','value8',但我无法让它工作来选择正确的记录。

谢谢。

+2

你知道数据不是第三范式吗?您是否考虑过先修复数据,然后TSQL语法更简单,并且查询执行更有效率? – Paparazzi 2012-04-03 14:15:43

+0

基于你想要记录1,2和3,那么你的意思是包含value1,value4,或value8 – Paparazzi 2012-04-03 19:20:14

+0

你是指一个表中包含所有的值和一个引用这些值的id的表? – 2012-04-04 06:21:07

回答

2

也许是这样的:

测试数据

CREATE TABLE Table1 
(
    id INT, 
    value VARCHAR(200) 
) 
INSERT INTO Table1 
VALUES 
    (1,'value1,value2,value3'), 
    (2,'value3,value4,value9'), 
    (3,'value4,value8,value9'), 
    (4,'value2,value3,value9') 

拆分功能

CREATE FUNCTION dbo.Split (@sep char(1), @s varchar(512)) 
RETURNS table 
AS 
RETURN (
    WITH Pieces(pn, start, stop) AS (
     SELECT 1, 1, CHARINDEX(@sep, @s) 
     UNION ALL 
     SELECT pn + 1, stop + 1, CHARINDEX(@sep, @s, stop + 1) 
     FROM Pieces 
     WHERE stop > 0 
    ) 
    SELECT pn, 
     SUBSTRING(@s, start, CASE WHEN stop > 0 THEN stop-start ELSE 512 END) AS s 
    FROM Pieces 
) 
GO 

查询

DECLARE @searchString VARCHAR(100) 
SET @searchString='value1,value4,value8' 
;WITH CTE 
AS 
(
    SELECT 
     split.s as searchString 
    FROM 
     dbo.Split(',',@searchString) AS split 
) 
SELECT 
    * 
FROM 
    Table1 
WHERE EXISTS 
(
    SELECT 
     NULL 
    FROM 
     dbo.Split(',',Table1.value) AS split 
    WHERE EXISTS 
    (
     SELECT 
      NULL 
     FROM 
      CTE 
     WHERE 
      CTE.searchString=split.s 
    ) 
) 

结果

id  value 
1  value1,value2,value3 
2  value3,value4,value9 
3  value4,value8,value9 

编辑

这种分裂函数以一个分离器和varchar分裂。它是一个递归函数,用于缓存该输入的varchar中的开始和结束位置。当计算开始和结束时,substring是一项很容易执行的任务。

+0

+1请解释分割功能 – Paparazzi 2012-04-03 19:19:10

+0

更新了答案 – Arion 2012-04-03 19:57:17

+0

哇,这是工作完美..谢谢.. – 2012-04-04 06:25:19

0

,如果你有码匹配价值和它的将是静态的,这可能工作:

select * from table where value like '%value1%' and value like '%value4%' and value like '%value8%' 

这是,如果你希望它包含的所有值。如果你希望它包含两种或然后切换“和”对“或”

编辑:在代码

有值,你可以在代码中动态生成SQL语句。

string statement = "select * from table where value like '%value%'"; 
foreach (string value in collectionOfValues) { 
     statement += " and value like '" + value + "'"; 
} 

我当然会使用SqlParameters而不是将值直接放在语句中,但是您会发现我的漂移。

+0

我从代码中获得的搜索字符串,并且是动态的。所以它可以是一个值或六个或其他。所以我必须拆分搜索字符串并从中选择一条语句。 – 2012-04-03 11:59:25

+0

我是否了解我的帖子上次编辑所需的内容? – 2012-04-03 12:06:34

+0

是的,我明白了。但我正在寻找一个解决方案,在存储过程中完成这一切。 – 2012-04-03 12:15:25

0

为了让你问什么,我认为你要么需要插入您的分离结果(不含单引号)到一个临时表,或让你的划分功能返回一个表。然后,你可以说:

SELECT column1, column2, column3 
FROM table1 
WHERE value in (select * from #values) 

OR

WHERE value in (select * from dbo.StringSplitFunc(...)) 

,这取决于接近你拿。