2014-02-20 65 views
1

我需要根據Person和語言插入一些數據庫關聯(MS-SQL Server 2008中的多對多表)。我的傳入數據包括一張滿是人的表格,一張充滿語言的表格,並且人們有一個代表與其關聯的每種語言的逗號分隔語言的字段在SQL中使用逗號分隔列表創建關聯

因此,這裏的表是什麼樣子

人民

----------------------------------------------- 
ID | First Name | Last Name | Languages 
----------------------------------------------- 
1 | Paul  | Johnson | English,Spanish 
2 | Jack  | Johnson | English,Hindi 
3 | Mark  | Johnson | NULL 
----------------------------------------------- 

語言

-------------- 
ID | Name 
-------------- 
1 | English 
2 | Spanish 
3 | Hindi 
--------------  

,我需要把它變成一個表,這將在完成後,如下所示:

PeopleLanguage

---------------------- 
PeopleID | LanguageID 
---------------------- 
1  | 1 
1  | 2 
2  | 1 
2  | 3 

現在,我喜歡避免使用遊標或while循環,以在每個迭代的醫生,並進行操作,但我不能說的外面想辦法(另外,我不完全理解遊標:p)

希望SO能夠爲我提出一個很好的解決方案。

謝謝!

回答

-1

假設上面的結構,我能夠像這樣結合在CHARINDEX檢查,以做到這一點:

INSERT INTO PeopleLanguages (PeopleID, LanguageID) 
SELECT P.Id, L.Id 
FROM People P 
JOIN Language L ON CHARINDEX(L.Name, P.Languages) > 0 
+1

這似乎工作正常(我沒有測試過實際的插入,但我有選擇顯示正確的數據)!但是,請注意,不是使用charindex,而是使用IN和一個自定義表值函數來分割逗號,如下所示:... JOIN語言ON Language.Name IN(SELECT DISTINCT [items] AS [LanguageName] FROM [BigSplit](People.Languages,',')) –

+1

[This fiddle](http://sqlfiddle.com/#!3/172c2/1)顯示了這個簡單的charindex檢查可以如何中斷。 –

+1

@Paul你可能應該發表你的答案(包括BigSplit的定義)作爲答案,並接受這一點,尤其是如果這就是你的選擇。目前這個答案不是一個非常安全的解決方案。 –

-1

哎喲......被秒......檢查SQL Fiddle下面的工作代碼。與drothe提出的類似。

Wrond code deleted 

你也可以從this other asnwer使用一些用途,並嘗試使用CTE的。

檢查根據Aaron Bertrand評論SQL Fiddle ...從我身邊不正確,需要包括更多測試並檢查CHARINDEX是否中斷。

嘗試這種解決方案(working code on SQL Fiddle

SELECT tbl.personID,l.LangID 
FROM LANG l JOIN 
(SELECT P.[PersonID], 
     LTRIM(RTRIM(n.r.value('.', 'varchar(500)'))) [Language] 
FROM People AS P 
     CROSS APPLY (
     SELECT CAST('<A>' + REPLACE([Languages], ',', '</A><A>') + '</A>' AS XML) 
     )   AS S(XMLCol) 
     CROSS APPLY S.XMLCol.nodes('/A') AS n(r)) tbl ON l.Name = tbl.[Language] 

SO question及其若干答案給你不同的方法,包括使用的一個。

在這裏你有一個long and detailed performance analysis如何使用CLR拆分字符串。

+1

認爲你需要小心(例如,語言可能是'英語','英語(加拿大)','英國(英國)','法國','法國(加拿大)'等)。可能比較安全,用逗號進行緩衝 –

+0

我的確也是這樣,@AaronBertrand。看到我對drothe答案的評論,這解釋了我的解決方案。希望這是正確的,它看起來是正確的:D –

+2

@PaulZaczkowski太棒了!接下來,你應該確保你的split函數是內聯的,而不是多語句,或者如果可能的話,CLR。一些比較在這裏:http://www.sqlperformance.com/2012/07/t-sql-queries/split-strings ...你也應該考慮一個不同的設計,恕我直言。 CSV字符串在數據庫中沒有位置。 –

相關問題