我有一个简单的查询,但我有多个需要过滤掉的记录。我正在使用狂野卡片这样的声明。有没有更好的方法来做到这一点,然后写出每一个?我可以创建一个它反映的udf表吗?怎么样?如果我能。谢谢:))
SELECT a.SalesOrderNo ,
a.ShipExpireDate ,
a.CustomerNo ,
b.ItemCode ,
b.LineKey ,
b.QuantityOrdered ,
b.QuantityShipped ,
b.ItemCodeDesc ,
b.ExplodedKitItem
FROM dbo.SO_SalesOrderHeader a
LEFT JOIN dbo.SO_SalesOrderDetail b
ON a.SalesOrderNo = b.SalesOrderNo
WHERE b.ItemType = '1'
AND b.ItemCodeDesc NOT LIKE '%Cert%'
AND b.ItemCodeDesc NOT LIKE '%Fee%'
AND b.ItemCodeDesc NOT LIKE '%Tag%'
AND b.ItemCode NOT LIKE 'GF%'
AND b.ItemCode NOT LIKE 'PXDIALPREP'
AND b.ItemCode NOT LIKE '/C%'
AND a.ShipExpireDate = CONVERT(DATE, GETDATE(), 101)
答案 0 :(得分:1)
这是一个不同的设计,可以让你将ItemCodeDesc放在一个单独的表中(这也可能是一个TVF)。我不能评论性能。
另外请注意,因为您是外部加入销售订单明细,所以此表可以包含NULL记录。当ItemType为NULL时,您的b.ItemType = '1'
将始终为FALSE。所以你也可以把它变成一个内连接(你可能会发现你的查询计划正在这样做)
SELECT a.SalesOrderNo ,
a.ShipExpireDate ,
a.CustomerNo ,
b.ItemCode ,
b.LineKey ,
b.QuantityOrdered ,
b.QuantityShipped ,
b.ItemCodeDesc ,
b.ExplodedKitItem
FROM dbo.SO_SalesOrderHeader a
LEFT JOIN dbo.SO_SalesOrderDetail b
ON a.SalesOrderNo = b.SalesOrderNo
WHERE b.ItemType = '1'
AND b.ItemCode NOT LIKE 'GF%'
AND b.ItemCode NOT LIKE 'PXDIALPREP'
AND b.ItemCode NOT LIKE '/C%'
AND a.ShipExpireDate = CONVERT(DATE, GETDATE(), 101)
AND NOT EXISTS (
SELECT 1 FROM dbo.MappingTable MT
WHERE b.ItemCodeDesc LIKE MT.ItemCodeDesc
)
答案 1 :(得分:0)
注意:我猜您的标准是为了过滤掉无法发货的商品类型(如费用),根据您的要求进行调整。
您遇到的问题是离散值存储在ID中的结果。看起来你应该有一个列IsShippable,或者更好的是ItemCodeType的代码表,其中包含Cert,Fee,Tag等行和IsShippable列。如果你有一个代码表,那么你就可以做到
inner join ItemCodeTypes ict on ict.ItemCodeTypeId = b.ItemCodeTypeId and ict.IsShippable = 1
CertCodeTypes表中的Cert,Fee,Tag,行将具有IsShippable = 0:
Id | Name | IsShippable
1 Cert 0
2 Fee 0
3 Tag 0
4 Product 1
5 Book 1
编辑:要更直接地回答您的问题,您可以制作这样的视图,然后当您从中查询时,可以轻松过滤Where IsShippable = 1:
Select CASE
When b.ItemCodeDesc LIKE '%Cert%' Then 0
When b.ItemCodeDesc LIKE '%Fee%' Then 0
--etc.
Else 1
END as IsShippable
,*
From dbo.SO_SalesOrderDetail