2014-10-29 70 views
6

我想征询一下您的建议,SQL服务器中的任何函数是否允许我为值列表执行部分匹配?TSQL - 使用LIKE实现多个值的部分匹配

需要匹配的整个字符串将通过存储过程传入​​。

我想在编写自己的函数之前先找到其他的替代方法,以逗号分割字符串,然后在将数据返回到程序之前合并所有结果。

例如,我会通过以下字符串到我的TSQL

苹果,橘子,梨

在我WHERE条款应符合

select * from store where fruits like 'apple%' 
select * from store where fruits like 'orange%' 
select * from store where fruits like 'pear%' 

我可以在单个SQL语句中实现上述结果而不是写入函数来破解每个字符串?

数据在我的表

apple red 
apple green 
orange sweet 
orange sour 
pear big 
pear small 

所以,当我在字符串中通过了 “苹果,梨”,我需要返回

apple red 
apple green 
pear big 
pear small 
+2

'水果'看起来像什么?不要说逗号分隔的值。对于关系数据库来说,这是一个非常非常糟糕的设计。 – 2014-10-29 01:13:01

+0

我只是用一个简单的表格来说明。 – user3015739 2014-10-29 03:28:06

+0

您的数据结构存在根本性问题。您不应该将事物列表存储为字符串。相反,你应该使用联结表。 – 2014-10-29 10:13:49

回答

1

试试这个,但性能会不太好

declare @parm varchar(200) 
set @parm = ','+'apple,orange,pear'+',' 

select * from store where charindex(fruit,@parm) > 0 
+0

它不起作用,因为在相同的数据中不能有苹果,桔子。我只是用模式匹配找到所有的苹果红,苹果绿,橙大,橙小。 – user3015739 2014-10-29 03:32:14

+0

对不起,输入 - 我颠倒了参数。尝试更改后的版本 – Sparky 2014-10-29 12:44:59

1

它可能很简单:

SELECT 
    * 
FROM 
    store 
WHERE 
    fruits LIKE 'apple%' 
    OR fruits LIKE 'orange%' 
    OR fruits LIKE 'pear%' 
+0

该字符串将从存储过程传入​​,我需要使用模式匹配返回数据集。我没有问题写一个函数来分割字符串,然后结合结果。试着去探索我有什么其他的选择。 – user3015739 2014-10-29 03:33:00

+1

我喜欢简单的解决方案 – 2016-06-20 08:56:42

7

您可以创建一个临时表作为

'CREATE TABLE #Pattern (
     SearchItems VARCHAR(20) 
    );' 

备注:请确保检查临时表是否存在以避免错误。 现在,你现在可以使用这个临时表中插入到临时表中检索词作为

'INSERT 
    INTO #Pattern 
    VALUES 
     ('% APPLE %'), 
     ('% ORANGE %'), 
     ('% BANANA %');' 

,使用INNER JOIN 像

'SELECT * 
FROM Store 
INNER JOIN #Pattern 
    ON Store.Fruits LIKE SearchItems 
' 

作为一个说明搜索你的表,临时表是什么我尽量避免大部分,但在这里它很方便,我使用这种解决方案的情况下不要求性能。相反,它更容易保持不断增长的searchItems的维护。

希望这也适用于其他人。

-1

有一种方法可以在SQL中完成,但它非常复杂。假设你可以生活在匹配一串最多三个水果名字的字符串中,你可以按照以下方式进行。

我们假设@fruits是含有水果的清单,这是我们添加更多的逗号分隔符(如果它含有少于三个水果名)的varchar变量:

declare @fruits varchar(80); 
set @fruits = <list of fruits passed in> + ',_,_,_,'; 

下面的公式是不是SQL ,但子行动背后的数学,我们需要为like表达式:

NOTE: NOT SQL 

First fruit word: 
p1 = charindex(',', @fruits)   << position of ',' delimiter 
v1 = substring(@fruits, 0, p1-1) + '%' << fruit word we seek 
r1 = substring(@fruits, p1+1)   << remainder of string 

Second fruit word:  
p2 = charindex(',', r1) 
v2 = substring(r1, 0, p2-1) + '%' 
r2 = substring(r1, p2+1) 

Third fruit word: 
p3 = charindex(',', r2) 
v3 = substring(r2, 0, p3-1) + '%' 
r3 = substring(r2, p3+1) 

...and so on... 

现在我们替代的p1第一的价值观,v1r1代入p2v2r2的第二组等式。同样,我们用第二组值代入第三组,等等。我们结束了这些怪物的v1v2,并且v3

v1 = substring(@fruits, 0, charindex(',', @fruits)-1) + '%' 
v2 = substring(substring(@fruits, charindex(',', @fruits)+1), 0, charindex(',', substring(@fruits, charindex(',', @fruits)+1))-1) + '%' 
v3 = substring(substring(substring(@fruits, charindex(',', @fruits)+1), charindex(',', substring(@fruits, charindex(',', @fruits)+1))+1), 0, charindex(',', substring(substring(@fruits, charindex(',', @fruits)+1), charindex(',', substring(@fruits, charindex(',', @fruits)+1))+1))-1) + '%' 

这些都是我们需要寻找前三LIKE值:

select * from fruits 
where fruit like <v1> 
    or fruit like <v2> 
    or fruit like <v3> 

完全展开,查询是:

select * from fruits 
where fruit like substring(@fruits, 0, charindex(',', @fruits)-1) + '%' 
    or fruit like substring(substring(@fruits, charindex(',', @fruits)+1), 0, charindex(',', substring(@fruits, charindex(',', @fruits)+1))-1) + '%' 
    or fruit like substring(substring(substring(@fruits, charindex(',', @fruits)+1), charindex(',', substring(@fruits, charindex(',', @fruits)+1))+1), 0, charindex(',', substring(substring(@fruits, charindex(',', @fruits)+1), charindex(',', substring(@fruits, charindex(',', @fruits)+1))+1))-1) + '%' 

只要我们喜欢,我们可以做更多的工作来提取第4个字,第5个字,第6个字等等。但每一个进一步的价值变得比以前更复杂。

注意:我还没有试过这个解决方案,我只用数学证明了它。