2014-10-29 73 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個字等等。但每一個進一步的價值變得比以前更復雜。

注意:我還沒有試過這個解決方案,我只用數學證明了它。