SQL不喜欢多个值

时间:2014-04-14 21:02:46

标签: sql sql-server

更新

我能够通过利用NOT EXISTS找到我的解决方案。因此,我的陈述看起来像这样:

and NOT EXISTS (select RejectCode from #rejects where od.UnitDescription LIKE ('%' + RejectCode + '%'))

这会利用临时表#results,其中我存储了184个拒绝代码。谢谢大家的回应。我沿着每条路走下去,学到了一些东西,回应让我找到了解决方案。

发布 - > CTE - >临时表(不能在CTE之后立即分配变量) - >加入LIKE - >不存在

更新

我试图用很多条件过滤查询 - 下面的嵌套选择语句返回184个拒绝代码。我有一个单位描述回来是一个VARCHAR(100),里面包含一个代码(不在静态点)。

我尝试执行以下操作(为简单起见总结了选择):

select od.*, o.*
from OrderDetails od
join Orders o ON o.oKey = od.oKey
where CustomerID = '104'
  and od.UnitDescription NOT LIKE (select RejectCode
                                   from [CustDiscountTables].[dbo].RejectDiscount 
                                   where GroupID = '15' 
                                     AND (DiscountPercent = '1' 
                                          or DiscountPercent = '.4' 
                                          or DiscountPercent = '.2'))

以前我只需要过滤几个代码,所以我只是做了#34;并且(od.UnitDescription NOT LIKE'%a%'和od.UnitDescription NOT LIKE&#39 ;%b%'和...等)。我的问题是:如何使用NOT LIKE或类似的东西(因为UnitDescription不是静态的并且包含的​​不仅仅是拒绝代码),来过滤嵌套select语句返回的所有代码?我真的注定要写出" NOT LIKE" 184次?

4 个答案:

答案 0 :(得分:2)

以下是我将如何操作 - 我无法看到您的确切示例,因此您可能需要在条件表中使用不同的列。

with criteria as
(
   select 15 as groupid, '1' as discountpercent
union all
   select 15 as groupid, '.4' as discountpercent
union all
   select 15 as groupid, '.2' as discountpercent
), rejects
(
   select distinct RejectCode 
   from [CustDiscountTables].[dbo].RejectDiscount rd
   join criteria c on c.groupid = rd.GroupID and c.discountpercent = rd.DiscountPercent
)
select od.*, o.*
from OrderDetails od
join Orders o ON o.oKey = od.oKey
where CustomerID = '104'
  and od.UnitDescription NOT LIKE (select RejectCode from rejects)

正如您所看到的,我正在CTE中制作标准信息,但这也可以在表中(如果您认为它会经常扩展。)您还可以添加更多列或更多条件子查询和然后根据需要将它们合并在拒绝CTE中。

例如,假设你在foo和fab上也有critera:

with criteria as
(
   select 15 as groupid, '1' as discountpercent
union all
   select 15 as groupid, '.4' as discountpercent
union all
   select 15 as groupid, '.2' as discountpercent
), critera2 as
(
   select 1 as foo, '1' as fab
union all
   select 2 as foo, '2' as fab
union all
   select 3 as foo, '3' as fab
), rejects as
(
   select distinct RejectCode 
   from [CustDiscountTables].[dbo].RejectDiscount rd
   join criteria c on c.groupid = rd.GroupID and c.discountpercent = rd.DiscountPercent
   union
   select distinct RejectCode 
   from foofabrejectlist foofab
   join criteria2 c2 on c2.foo = foofab.foo and c2.fab = foofab.fab

)
select od.*, o.*
from OrderDetails od
join Orders o ON o.oKey = od.oKey
where CustomerID = '104'
  and od.UnitDescription NOT LIKE (select RejectCode from rejects)

正如您所看到的,这可以很快变得非常“复杂”,但仍然易于维护或动态化(通过将标准添加到表中。)

评论中要求的其他信息:

要使用连接而不是“不喜欢”,请执行以下操作:

select od.*, o.*
from OrderDetails od
join Orders o ON o.oKey = od.oKey
left join rejects on od.UnitDescription = rejects.RejectCode
where CustomerID = '104'
  and rejects.RejectCode is null

注意:如果您将SQL优化器编写为连接或使用IN语法,那么它应该生成相同的执行计划。

答案 1 :(得分:2)

另一种方法可能是首先过滤那些“喜欢”的ID,然后选择那些“不在”返回的ID(这假设你在OrderDetails中有一个列id):

select od.*, o.*
from OrderDetails od
join Orders o ON o.oKey = od.oKey
where CustomerID = '104' and od.id not in (select od2.id 
                                           from OrderDetails od2 
                                           inner join [CustDiscountTables].[dbo].RejectDiscount rd on od2.UnitDescription LIKE '%' + rejectCode + '%'
                                           where od2.CustomerID = '104' 
                                                 and rd.GroupID = '15' 
                                                 and (rd.DiscountPercent = '1' 
                                                 or rd.DiscountPercent = '.4' 
                                                 or rd.DiscountPercent = '.2'))

答案 2 :(得分:0)

假设您的子查询返回了您想要的结果,并且唯一的问题是如何使用带有% LIKE通配符的“RejectCode”,您可以通过使用字符串连接来解决这个问题。我的想法是LIKE '%abc%`` is equivalent to LIKE'%'+'abc'+'%'`,因此您可以使用此概念来解决您的问题。像这样:

select od.*, o.*
from OrderDetails od
join Orders o ON o.oKey = od.oKey
where CustomerID = '104'
  and od.UnitDescription NOT LIKE '%' + (select RejectCode
                                        from [CustDiscountTables].[dbo].RejectDiscount 
                                        where GroupID = '15' 
                                        AND (DiscountPercent = '1' 
                                             or DiscountPercent = '.4' 
                                             or DiscountPercent = '.2')) + '%'

答案 3 :(得分:-1)

如果我理解您的要求,则拒绝代码是UnitDescription的一部分,与UnitDescription不完全相同。因此,在查询中使用RejectCode作为前缀和后缀%应该有效。试试这个:

select od.*, o.*
from OrderDetails od
join Orders o ON o.oKey = od.oKey
where CustomerID = '104'
and od.UnitDescription NOT LIKE (select '%' + RejectCode + '%'
                               from [CustDiscountTables].[dbo].RejectDiscount 
                               where GroupID = '15' 
                                 AND (DiscountPercent = '1' 
                                      or DiscountPercent = '.4' 
                                      or DiscountPercent = '.2'))

希望它有所帮助。