2013-05-01 35 views
0

我有3個表:是否有這樣的事,作爲一個「是」查詢

Silk_Skey Name 
1 Black White Checks Yellow Arms 
2 Black Crimson Stripes 
3 Crimson Yellow Stripes 

Sub Colour Major Colour 
Black Black 
White White 
Yellow Yellow 
Crimson Red 

MajorColour_Skey Major Colour 
1 Black 
2 White 
3 Yellow 
4 Red 

我要實現這一點:

ID Silk_Skey MajorColour_Skey 
1 1 1 
2 1 2 
3 1 3 
4 2 1 
5 2 4 
6 3 3 
7 3 4 

我需要做的就是創建一個鏈接表匹配3個表中的所有顏色並分解絲印名稱,以便在新表中顯示4行)請參閱下面的SQL。我的老闆建議我使用「IS IN」查詢,但我不知道你能提供什麼幫助?

SELECT s.Silks_Skey, mc.MajorColour_Skey 
FROM Silks s INNER JOIN SubColour sc on sc.SubColour **'IS IN HERE'** s.SilksName 
INNER JOIN MajorColour mc 
ON sc.MajorColour = mc.MajorColour 
+0

是的,這就是所謂的[在](https://www.google.com/search?q=sql+in&aq=f&oq=sql+in&aqs=chrome.0.57j0l2j65j5j60.1266j0&sourceid=chrome&ie=UTF-8 ) – MikeTheLiar 2013-05-01 14:34:44

+2

從您的描述中,它聽起來像s.silkname是一個varchar列,可能包含多種顏色,你想匹配的顏色名稱字段?如果是這種情況,你需要通配符搜索,否則一個簡單的IN將起作用,如果你的FID爲FK – munch1324 2013-05-01 14:37:07

+0

我已經編輯過我的文章,我希望這可以幫助,因爲我不明白你的建議是什麼我。謝謝 – wafw1971 2013-05-01 14:47:13

回答

3

您可以使用IN

AND table.column IN ('a','b','c') 

AND table.column IN (1,2,3) 

,或者如果你正在尋找的東西像一個字符串,你可以做

AND table.column LIKE '%word' -- table.column ends with 'word' 
AND table.column LIKE 'word%' -- table.column starts with 'word' 
AND table.column LIKE '%word%' -- table.column has 'word' anywhere in the column 
+0

我已經編輯過我的帖子,我希望這可以幫助,因爲我不明白你的建議告訴我什麼。謝謝 – wafw1971 2013-05-01 14:47:59

1

對於你想要做的事情,你需要做人字符串因爲你試圖將一種顏色與一個字符串中的顏色列表進行比較。

like運營商可以做到這一點。試試這個on條款:

on ' '+ s.SilksName +' ' like '% '+sc.SubColour+' %' 

這種檢查是否在列表中(s.SilksName)給定的顏色(sc.SubColour)英寸例如,如果您有像「RED GREEN」這樣的列表,它將匹配「%RED%」或「%GREEN%」。

連接空格的目的是爲了避免部分詞匹配。例如,「藍綠」可以匹配沒有分隔符的「藍色」和「綠色」。

以下查詢返回7行,這似乎是正確的(3爲在絲綢中的第一行和2的每個其他兩個的):

with silks as (
     select 1 as silks_skey, 'Black White Checks Yellow Arms' as silksname union all 
     select 2, 'Black Crimson Stripes' union all 
     select 3, 'Crimson Yellow Stripes' 
    ), 
    subcolour as (
     select 'black' as subcolour, 'black' as majorcolour union all 
     select 'white', 'white' union all 
     select 'yellow', 'yellow' union all 
     select 'crimson', 'red' 
    ), 
    MajorColour as (
     select 1 as MajorColour_skey, 'black' as MajorColour union all 
     select 2, 'white' union all 
     select 3, 'yellow' union all 
     select 4, 'red' 
    ) 
SELECT s.Silks_Skey, mc.MajorColour_Skey 
FROM Silks s INNER JOIN SubColour sc on ' ' + s.SilksName + ' ' like '% ' + sc.SubColour + ' %' 
INNER JOIN MajorColour mc 
ON sc.MajorColour = mc.MajorColour 
+0

連接's.SilksName'兩邊的空格的目的是什麼?另外我不確定我會同意將它稱爲「字符串操作」。你在比較字符串,你沒有真正操縱它們。 – 2013-05-01 14:45:56

+0

我已經編輯過我的帖子,我希望這可以幫助,因爲我不明白你的建議告訴我什麼。謝謝 – wafw1971 2013-05-01 14:48:18

+0

嗨戈登在您的幫助下查詢的作品,但我沒有得到我期待的金額。我有4排,而不是17 – wafw1971 2013-05-01 14:54:04

1

這是註定要的性能很差,設計尷尬和痛苦的寫查詢。如果你的數據庫永遠不會很大,那麼它可能是可行的,但如果它會很大,你不能使用這個設計結構,並希望具有良好的性能,因爲你將無法正確使用索引。就我個人而言,我會添加一個與絲綢桌有關的絲綢顏色表,並個性地存儲顏色。數據庫設計的第一條規則之一是從不在一個字段中存儲多條信息。您正在存儲的列表總是意味着您需要一個相關的表來有效地使用數據庫。

一個線索,一個壞的(並且隨着時間的推移,通常行不通)數據庫設計是,如果你需要使用的功能或任何類型的caluations或者如果你需要一個像子句短語開始使用通配符來加入。現在解決這個問題,事情會更順利,維護將花費更少的時間,性能會更好。你目前的結構完全沒有好處。

您可能需要花一些額外的時間來分析和存儲絲綢名稱的個別顏色,但在查詢數據庫時保存的時間將非常重要,因爲您現在可以使用連接,然後使用索引。搜索fn_split,您將看到一種將絲綢名稱拆分爲單個顏色的方法,您可以在插入記錄時使用這些顏色。

如果你愚蠢地決定保留當前的結構,然後看看使用fuilltext搜索。它將比使用帶有通配符的類似子句作爲第一個字符更快。

+0

嗨HLGEM 至少有22000不同的絲綢組合,所以這是最好的前進方向。 謝謝 – wafw1971 2013-05-01 15:03:27

+0

越多的組合,在選擇時間嘗試解析就越糟糕。你的設計有不可避免的缺陷。您選擇不考慮在設計時您將如何處理數據,現在您將付出代價,因爲沒有好的方法來加入您的數據。由於重要的是數據完整性,性能和安全性,所以在設計數據庫時考慮到開發的簡易性。正如你發現在一個地方發展的容易意味着另一個地方更痛苦。重新設計是您的最佳選擇。沒有它就無法有效解決這個問題。 – HLGEM 2013-05-01 15:20:59

0

聽起來像你真正想要做的是將空間上的Name字段拆分,然後對顏色表中包含的每個值進行拆分(將子顏色連接在一起,因爲主要顏色是有效的子顏色太)你想要一個新的表中的條目。問題是沒有用於拆分字符串的內在T-SQL函數。要做到這一點,你最好的選擇是訪問Erland Sommarskog's關於如何做到這一點的明確答案。

一個替代方案,一個不是很整齊,可能或不可行的方法是在謂詞中使用CONTAINS關鍵字。然而,爲了達到這個目的,你需要使用全文索引 ,並且我懷疑用分割字符串和SQL中的數組的方式使用Erland的優秀giudes會更加合適和更快。

0

這是答案的人,謝謝你的所有想法。

Select S.[Silks_Skey], MC.[MajorColour_Skey] 
from [dbo].[Silks] S 
inner join [dbo].[SubColour] SC on CHARINDEX(SC.[SubColour],S.[SilksName]) <> 0 
inner join [dbo].[MajorColour] MC on SC.[MajorColour] = MC.[MajorColour] 

UNION ALL 

Select S.[Silks_Skey], MC.[MajorColour_Skey] 
from [dbo].[Silks] S 
inner join [dbo].[MajorColour] MC on CHARINDEX(MC.[MajorColour],S.[SilksName]) <> 0 

ORDER BY S.[Silks_Skey] 
相關問題