2013-05-01 84 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] 
相关问题