2015-10-05 88 views
1

Hello SQL Server專家。請幫助我以高效的方式將布爾邏輯(和,或)應用於SQLsServer中以逗號分隔的輸入字符串。用於SQL Server的逗號分隔輸入字符串

實施例:

DECLARE @ATable TABLE(ID INT, Value varchar(50)) 

INSERT INTO @ATable 
VALUES (1, 'A'), (1, 'B'), (1, 'C'), (2, 'C'), (2, 'D'), (3, 'A'), (4, 'B') 

declare @inputStr varchar(max) 
set @inputStr = 'A,B,C,D' 

declare @andOr varchar(30) -- can be either 'and' or 'or' 

if @andOr = 'and',我想獲得具有值的A和B二者,在上述表中的結果將是與ID 1的數據ID,這樣的結果將是

ID | Values 
----------- 
1 | A,B,C 

if @andOr = 'or',我想獲得具有值的A或B在上述表中的結果將是與編號1,3和4的數據ID,這樣的結果將是

ID | Values 
----------- 
1 | A,B,C 
3 | A 
4 | B 

謝謝。

+0

我已經使用動態SQL嘗試,但它變得很慢時 – WorkInProgress

+4

您需要輸入字符串的長度增加將字符串拆分成單獨的行以便能夠最好地處理任何類型的查詢。更好的是 - 首先有一個表值參數而不是字符串! – Bridge

+0

對於AND情況,您需要執行Bridge建議的操作。 IN子句通常適用於你的OR案例。 –

回答

2

請測試下面的SQL Select語句

你要注意的是SQL string split function 可以將數據庫

上創建用戶定義分裂功能的副本我使用COUNT() aggregate function with Partition By條款的第一件事。對於程序員來說,這也是T-SQL的一大提升。我用它來檢查所有輸入參數字符串段是否與@atable值匹配

最後一個技巧是string concatenation in SQL用於顯示。我用「對於XML路徑」字符串連接,以滿足您的要求

DECLARE @ATable TABLE(ID INT, Value varchar(50)) 
INSERT INTO @ATable VALUES (1,'A'),(1,'B'),(1,'C'),(2,'C'),(2,'D'),(3,'A'),(4,'B') 

declare @inputStr varchar(max) 
set @inputStr='A,B' 
declare @andOr varchar(30) 

set @andOr='and' 

SELECT 
    t.ID, 
    STUFF(
    (
     SELECT ',' + t1.Value 
     FROM @ATable t1 
     WHERE t1.ID = t.ID 
     FOR XML PATH(''),TYPE 
    ).value('.','VARCHAR(MAX)' 
    ), 1, 1, '') as [Values] 
FROM (
    select 
     distinct ID 
    from (
    select 
     s.cnt, t.*, 
     tcount = count(t.value) over (partition by t.id) 
    from (
     select *, cnt = count(*) over (partition by 1) from dbo.split(@inputStr,',') s 
    ) s 
    left join @ATable t on s.val = t.value 
    ) r 
    where tcount = cnt 
) t 

set @andOr='or' 

SELECT 
    t.ID, 
    STUFF(
    (
     SELECT ',' + t1.Value 
     FROM @ATable t1 
     WHERE t1.ID = t.ID 
     FOR XML PATH(''),TYPE 
    ).value('.','VARCHAR(MAX)' 
    ), 1, 1, '') as [Values] 
FROM (
    select 
     distinct t.ID 
    from dbo.split(@inputStr,',') s 
    inner join @ATable t on s.val = t.value 
) t 

結果是 enter image description here