是否存在“IS IN”查询这样的事情

时间:2013-05-01 14:32:37

标签: sql tsql

我有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

5 个答案:

答案 0 :(得分: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

答案 1 :(得分:1)

对于你想要做的事情,你需要进行字符串操作,因为你试图将一种颜色与一个字符串中的颜色列表进行比较。

like运算符可以执行此操作。试试这个on条款:

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

这将检查列表中是否有给定颜色(sc.SubColour)(s.SilksName)。例如,如果你有一个像'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

答案 2 :(得分:1)

这是一种注定要表现不佳的设计,并且编写查询时会感到尴尬和痛苦。如果你的数据库永远不会很大,那么它可能是可行的,但是如果它很大,你就不能使用这种设计结构并希望有良好的性能,因为你将无法正确使用索引。我个人会添加一个与丝绸表相关的丝绸颜色表,并单独存储颜色。数据库设计的第一条规则之一是永远不会在一个字段中存储多条信息。您正在存储一个列表,这意味着您需要一个相关的表来有效地使用数据库。

如果您需要使用任何类型的函数或caluations进行连接,或者如果您需要在like子句中的短语开头使用通配符,那么对于错误(以及随着时间推移通常不可行)数据库设计的一个线索就是。现在解决这个问题,事情会更加顺畅,维护将花费更少的时间,而且性能会更好。你现在的结构没有任何好处。

您可能需要花费一些额外的时间来按照单独的颜色来解析和存储丝绸名称,但是在查询数据库时节省的时间将非常重要,因为您现在可以使用连接然后使用索引。搜索fn_split,您将看到一种将丝绸名称拆分为单个颜色的方法,您可以在插入记录时使用这些颜色。

如果您愚蠢地决定保留当前结构,那么请考虑使用fuilltext搜索。它会比使用带有通配符的like子句作为第一个字符更快。

答案 3 :(得分:0)

听起来你真正想做的就是在空格上分割Name字段,然后在颜色表中包含这些值中的每一个(在主要颜色有效的情况下连接在子颜色上)子颜色)你想要一个新表中的一个条目。问题是没有内在的T-SQL函数来分割字符串。要做到这一点,最好的办法是访问Erland Sommarskog's关于如何执行此操作的明确答案。

另一种方法是,在你的谓词中使用CONTAINS关键字,它不是很整洁,可能有效或可能无效。但是,为了实现这一点,您需要使用全文索引 我怀疑使用Erland的优秀giudes来分割字符串和SQL中的数组将更合适,更快。

答案 4 :(得分: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]