2016-10-04 105 views
0

我有一個包含逗號分隔字符串的字段的表。我想創建的查詢返回的結果如下:T-SQL中的拆分功能

我想創建查詢,返回分割文本。對於exapmle:

數據表:

| ID         | Names       | 
| ------------------------------------ | -------------------------------- | 
| 63F5D993-3AC9-4EEA-8007-B669542BAD9A | John Smith,Kerry King,Tom Arraya | 

要求的結果:

ID         | Names        
------------------------------------ | ----------- 
63F5D993-3AC9-4EEA-8007-B669542BAD9A | John Smith      
------------------------------------- | ----------- 
63F5D993-3AC9-4EEA-8007-B669542BAD9A | Kerry King      
------------------------------------- | ----------- 
63F5D993-3AC9-4EEA-8007-B669542BAD9A | Tom Arraya 

我發現T-SQL,但其作品不太適合我的情況 「分裂」 的功能。我不能這樣執行它:

SELECT dbo.Split(dbo.name, ',') FROM dbo.Mytable 

它只能執行如下:

​​

但它並不適合我。 此外,我試圖寫光標:

DECLARE @bkb varchar(256) 
DECLARE @Bkb_Cursor CURSOR 
SET @Bkb_Cursor = CURSOR SCROLL FOR 
SELECT bkb.best_know_by 
    FROM [sugarcrm_cmsru_dev].[dbo].[contacts] c 
    left JOIN [dbo].[email_addr_bean_rel] eb 
    ON eb.[bean_id] = c.[id] 
    JOIN [dbo].[email_addresses] ea 
    ON ea.[id] = eb.[email_address_id] 
    JOIN [dbo].[contacts_cstm] ccs 
    ON eb.bean_id = ccs.id_c 
    left JOIN [dbo].[BestKnowBy$] bkb 
    ON c.[campaign_id] =bkb.Con_id 
    where c.deleted = 0; 
OPEN @Bkb_Cursor; 
FETCH NEXT FROM @Bkb_Cursor 
INTO @bkb; 
WHILE @@FETCH_STATUS = 0 
BEGIN 
     PRINT dbo.Splitfn(@bkb); 
     FETCH NEXT FROM @Bkb_Cursor INTO @bkb; 
END 
CLOSE @Bkb_Cursor; 
DEALLOCATE @Bkb_Cursor; 
GO 

但它不工作。我收到錯誤「列」dbo「在此上下文中不允許,並且找不到用戶定義的函數或集合」dbo.Splitfn「。」

我該如何解決這個問題?

我的查詢看起來如下:

SELECT c.[id], 
     bkb.best_know_by 
    FROM [sugarcrm_cmsru_dev].[dbo].[contacts] c 
    left JOIN [dbo].[email_addr_bean_rel] eb 
    ON eb.[bean_id] = c.[id] 
    JOIN [dbo].[email_addresses] ea 
    ON ea.[id] = eb.[email_address_id] 
    JOIN [dbo].[contacts_cstm] ccs 
    ON eb.bean_id = ccs.id_c 
    left JOIN [dbo].[BestKnowBy$] bkb 
    ON c.[campaign_id] =bkb.Con_id 
    where c.deleted = 0; 

的bkb.best_know_by字段包含逗號分隔字符串。我如何在這種情況下使用「交叉應用」?

+0

我想在您的查詢的連接是錯誤的,因爲ea'之間'了'INNER JOIN'和'eb'意味着'c'和'eb'之間的'INNER JOIN'。既然你使用'LEFT OUTER JOIN'來''bkb',你可能想使用'OUTER APPLY'而不是'CROSS APPLY'。 'OUTER APPLY'表現得像一個'LEFT OUTER JOIN',這意味着即使函數自身沒有返回行(函數返回的列將作爲NULL輸出),行也會被返回。一個'CROSS APPLY'意味着一個'INNER JOIN',所以只有當函數有相應的行時纔會返回行。 – knuckles

回答

1

跨應用會做的伎倆

Select A.ID 
     ,Names = B.Item -- << Return Field from your Split Function 
From YourTable A 
Cross Apply (Select * from dbo.Split(A.Names, ',')) B 

有了您的查詢

SELECT c.[id] 
     ,S.*  --<< Removed bkb.best_know_by and Replaced with S.* (don't know your Split() Return Field) 
FROM [sugarcrm_cmsru_dev].[dbo].[contacts] c 
LEFT JOIN [dbo].[email_addr_bean_rel] eb ON eb.[bean_id] = c.[id] 
JOIN [dbo].[email_addresses] ea ON ea.[id] = eb.[email_address_id] 
JOIN [dbo].[contacts_cstm] ccs ON eb.bean_id = ccs.id_c 
LEFT JOIN [dbo].[BestKnowBy$] bkb ON c.[campaign_id] =bkb.Con_id 
Cross Apply dbo.Split(bkb.best_know_by,',') S 
where c.deleted = 0; 
+1

您不需要將分割函數包裝在子查詢中 - 「Cross Apply dbo.Split(A.Names,',')B'將產生與'Cross Apply(從* dbo.Split(A * .Names,','))B' – knuckles

+0

@knuckles是的你是正確的..粉筆這OCD和舊習慣。沒有性能打擊,如果你只想選擇第一和第三項(例如)它將不得不被包裝 –

+0

我添加了細節到我的問題。敬請期待。謝謝。 – Seva

3

你需要與你的表的結果集組合將執行功能的每一行使用CROSS APPLY

SELECT st.ID, spl.value 
FROM SplitTest st 
CROSS APPLY string_split(st.Names, ',') spl 

results

編輯: 關於增加你的查詢對您的問題,您可以執行以下操作:

;WITH CTE_Query AS (
    SELECT c.[id], 
     bkb.best_know_by 
    FROM [sugarcrm_cmsru_dev].[dbo].[contacts] c 
    left JOIN [dbo].[email_addr_bean_rel] eb 
    ON eb.[bean_id] = c.[id] 
    JOIN [dbo].[email_addresses] ea 
    ON ea.[id] = eb.[email_address_id] 
    JOIN [dbo].[contacts_cstm] ccs 
    ON eb.bean_id = ccs.id_c 
    left JOIN [dbo].[BestKnowBy$] bkb 
    ON c.[campaign_id] =bkb.Con_id 
    where c.deleted = 0 
) 
SELECT cte.id, spl.value 
FROM CTE_Query AS cte 
CROSS APPLY string_split(cte.best_know_by, ',') spl 
+0

我在我的問題中添加了詳細信息。敬請期待。謝謝。 – Seva

+1

沒有選擇分開你的表結構,我建議你把所有東西都包裝在CTE /子查詢中,然後執行'CROSS APPLY'。請參閱編輯。 –