2010-01-03 119 views
3

我在表中有兩列,分別叫做TaskSetSkillsSelectedSQL 2005中的TSQL:查詢

的樣本數據如下:

TaskSet      | SkillsSelected 
-------------------------------------------------- 
SK000001, SK000004, SK000002 | SK000001, SK000002, SK000003 
SK000002      | SK000002, SK000003, SK000004 

正如你可以看到它使用逗號將數據分隔。我想要一個查詢,會給我不是從taskset的未在SkillsSelected存在的記錄,因此在這種情況下,將返回:

SK000003 
SK000003, SK000004 
+1

作爲@JFreedman說,這是用於存儲這些數據完全不恰當的結構。你看過導入平面文件數據的不同方法嗎?例如,SSIS應該能夠將這些數據分開,然後將其寫入正確規範化的數據庫。 – 2010-01-03 23:40:00

+0

@David Hall。這是我的一個限制,因爲他們提供的數據已經在這種格式上,因爲它們是平坦的平面遷移。我知道這並不理想,但我必須處理這些數據。 – dcpartners 2010-01-04 01:13:58

+0

你已經改變了這個問題,所以我添加了我的答案。 – 2010-01-04 01:25:00

回答

3

首先,實現您在得到CLR斯普利特()函數SQL 2005安裝介質上的示例。

SELECT t.*, s.value 
FROM yourTable t 
CROSS APPLY 
dbo.Split(SkillsSelected) s 

EXCEPT 

SELECT t.*, s.value 
FROM yourTable t 
CROSS APPLY 
dbo.Split(TaskList) s 
; 

或者,您可以使用數字表,這將工作得很好,並且不會強制您打開CLR。

[編輯]編輯在列表中包括t。*。這實際上應該改爲使用t的PK或其他識別特徵。

[編輯]抱歉 - 讓他們錯了方向。

而現在,這個問題已經改變了,讓我們來解決串聯太:

SELECT t.*, 
STUFF(
(
    SELECT ', ' + value 
    FROM 
    (
    SELECT s.value 
    FROM 
    dbo.Split(SkillsSelected) s 
    EXCEPT 
    SELECT s.value 
    FROM 
    dbo.Split(TaskList) s 
    ) v 
    FOR XML PATH('') 
),1,2,'') AS MissingSkills 
FROM yourTable AS t; 
+0

如果記錄有多於1行,那麼這種方法效果很好。如果我得到了從表格返回到逗號分隔的功能。但是當時如何返回1排。如果你明白我的意思? – dcpartners 2010-01-04 01:05:19

+0

它的工作原理!謝謝。我很高興我不使用光標:) – dcpartners 2010-01-04 01:35:59

3

這不是存儲數據的最佳方式。爲什麼這一切都在一個記錄?它應該更加標準化。

+0

我同意這一個。但數據是從平面文件中得到的,我無能爲力。 – dcpartners 2010-01-03 23:29:59

+2

但是您不讀取平面文件,這意味着您正在將平面文件插入到SQL表中。那時,你應該正常化。 – 2010-01-03 23:39:16

+2

爲什麼這個答案在沒有回答提出的問題時收到這麼多票?數據模型的改變不是微不足道的。對JFreedman沒有不尊重,但這應該是像David Hall所作的評論。我意識到該帳戶沒有足夠的代表發表評論。 – 2010-01-04 00:55:33

0

我把這個規範發送給誰設計表​​非常可怕!

我會這樣做使用CLR存儲過程,它可能與光標,但代碼將是可怕的。

6

在SQL Server中處理逗號分隔列表的最好方法是創建一個返回表類型的UDF。請參閱this link for details。 MS文檔聲稱CLR UDF更快,但here's an actual comparison of the two options in use

一旦到位,你可以使用:

SELECT t.* 
    FROM TABLE t 
WHERE EXISTS(SELECT value 
       FROM dbo.split(t.taskset) 
       INTERSECT 
       SELECT value 
       FROM dbo.split(t.skillsselected)) 

參考:

+0

使用CLR函數而不是簡單的tsql UDF是否有特殊原因?此外,你給的鏈接只是普通的SQL - 創建CLR UDF的鏈接詳細信息http://davidhayden.com/blog/dave/archive/2006/04/18/2917.aspx – 2010-01-03 23:30:14

+0

謝謝我將採取這種方法 – dcpartners 2010-01-03 23:31:37

+0

@OMG Ponies謝謝 - 我想這是出於性能原因,只是想檢查。我一直使用普通的UDF完成CSV拆分,但可能在將來必須切換到使用CLR。 – 2010-01-03 23:37:24