2014-10-08 88 views
1

我搜索了很多論壇和網站,一直沒能找到解決方案。也許我不是在尋找正確的東西 - 但任何方向和援助將不勝感激!傳遞多個字符串和多個值作爲參數

我想加入兩個表格:UserDataServiceStatsUserData由以下各列和樣本數據:

Title   Application 
------------ ------------- 
Site Manager KB1245;KB3256 
FTP_Viewer  FTP1536 

ServiceStats由以下各列和樣本數據:

ApplicationName Vendor 
--------------- ------------ 
KB1245    Kronos 
KB3256    Kronos2 
FTP1536   File Manager 

當加入我需要得到類似以下的輸出表:

Site Manager KB1245 Kronos 
Site Manager KB3256 Kronos2 
FTP_Viewer FTP1536 File Manager 

我的問題是讓連接閱讀和識別何時有多個ApplicationNamesTitle

再次 - 感謝任何幫助和指導。

+3

您已在'UserData.Application'列中分隔數據。 **不要這樣做** **字段中的分隔數據是常見的數據庫反模式。修正模式,使每個值在數據庫中都有自己的位置,突然間,這個連接問題變得很容易。 – 2014-10-08 19:53:29

+0

我已經與團隊聯繫過了 - 但不幸的是我無法改變它。還有其他幾項基於該分隔字段的項目。 – user3813523 2014-10-08 20:32:50

回答

0

我可以削減OP一些鬆懈。作爲開發者,我們不得不處理由他人做出的不太理想的決定。 OP應該搜索的是如何分割分隔字符串,在StackOverflow中有多個字符串。

我的解決辦法:

;WITH 
    cte1 AS (
     SELECT Title, 
       REPLACE(Application,' ','') + ';' AS Application 
     FROM UserData 
    ), 
    cte2 AS (
     SELECT Title, 
       LEFT(Application,CHARINDEX(';',Application)-1)  AS ApplicationName, 
       STUFF(Application,1,CHARINDEX(';',Application),'') AS RemainingApp 
     FROM cte1 
     UNION ALL 
     SELECT Title, 
       LEFT(RemainingApp,CHARINDEX(';',RemainingApp)-1), 
       STUFF(RemainingApp,1,CHARINDEX(';',RemainingApp),'') 
     FROM cte2 
     WHERE LEN(RemainingApp) > 0 
    ) 

SELECT c2.Title, 
     c2.ApplicationName, 
     s.Vendor 
FROM cte2 c2 
INNER JOIN ServiceStats s ON c2.ApplicationName = s.ApplicationName 
+0

我必須做一些調整才能在我的具體實例中工作 - 但這確實給了我正確的方向。 – user3813523 2014-10-09 13:39:32

0

我更喜歡使用一個表值函數,讓我加入到它。這也使我的代碼更小,當我不得不使用它:

ALTER FUNCTION [dbo].[Split](@String VARCHAR(8000), @Delimiter CHAR(1))  
RETURNS @temptable TABLE (item VARCHAR(8000))  
AS  
BEGIN  
    DECLARE @idx INT  
    DECLARE @slice VARCHAR(8000)   
    SELECT @idx = 1  
    IF len(@String)<1 OR @String IS NULL RETURN  
    while @idx!= 0  
    BEGIN  
     SET @idx = charindex(@Delimiter,@String)  
     IF @idx!=0  
      SET @slice = LEFT(@String,@idx - 1)  
     ELSE  
      SET @slice = @String  
     IF(len(@slice)>0) 
      INSERT INTO @temptable(Item) VALUES(@slice)  
     SET @String = RIGHT(@String,len(@String) - @idx)  
     IF len(@String) = 0 break  
    END 
    RETURN  
END 

然後使用它:

SELECT * FROM dbo.Split('1;2;3;4;5',';') 

它的工作原理就像一個表,你甚至可以加入到它:

SELECT * 
FROM dbo.Split('1;2;3;4;5',';') a 
INNER JOIN MyTable b ON a.item = b.Field1 
相關問題