2016-10-04 6 views
0

昏睡区切り文字列を含むフィールドを持つテーブルがあります。私は結果を返すクエリのthatsを作成whant作成: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 

Iは、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フィールドはコンマは、文字列を分離含まれています。この場合、どのように「クロス・アプライ」を使用できますか?クエリの追加に関して :

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

results

編集:あなたが行ごとに関数を実行しますあなたのテーブルの結果セットと組み合わせてCROSS APPLYを使用する必要が

+0

私はあなたのクエリに参加すると思いますが、間違っているのでea' ''間INNER JOIN'と'eb'は' c'と 'eb'の間の' INNER JOIN'を意味します。 'LEFT OUTER JOIN'を' bkb'に使ったので、 'CROSS APPLY'の代わりに' OUTER 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(Select * from dbo.Split(A .Names、 '、'))B' – knuckles

+0

@knucklesはい、あなたは正しいです。これをOCDと古い習慣に変えてください。パフォーマンスヒットはなく、たとえば1番目と3番目のアイテムだけを選択したい場合は、それをラップする必要があります。 –

+0

私は自分の質問に詳細を追加しました。見てください。ありがとう。 – Seva

3

あなたの質問には、以下を行うことができます:

;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'を実行することをお勧めします。編集を参照してください。 –