您可以在ON
子句中包含复杂的条件。使用 aLEFT OUTER JOIN
允许您处理子句中的奇数情况 (TX37) WHERE
。
请注意,子句R
中的引用WHERE
必须处理 NULL 以避免将外连接转换为内连接。
select L.*
from dbo.Orders as L left outer join
dbo.Orders as R on R.OrderId = L.OrderId and (
( L.Code = 'TX33' and R.Code = 'TX34' ) or
( L.Code = 'TX35' and R.Code = 'TX36' ) or
( L.Code = 'TX38' and R.Code = 'TX39' ) )
where L.PurchaseDate is not NULL and ( L.Code = 'TX37' or R.Code is not NULL )
如果您真的只想要包含 TX33、TX34和一个或多个其他模式的订单,那么它会稍微复杂一些。使用group by L.OrderId
with acount( L.OrderId )
可以让您找到在模式中有两个或多个匹配的订单。它开始接近这样的事情:
declare @Orders as Table ( Id Int Identity, OrderId Int, Code VarChar(4), PurchaseDate Date )
insert into @Orders ( OrderId, Code, PurchaseDate ) values
( 1, 'TX37', GetDate() ),
( 2, 'TX37', GetDate() ), ( 2, 'FOO', GetDate() ),
( 3, 'TX33', GetDate() ), ( 3, 'TX34', GetDate() ),
( 4, 'TX33', GetDate() ), ( 4, 'TX34', GetDate() ), ( 4, 'TX37', GetDate() ),
( 5, 'TX33', GetDate() ), ( 5, 'TX34', GetDate() ), ( 5, 'TX35', GetDate() ),
( 5, 'TX36', GetDate() ),
( 6, 'TX33', GetDate() ), ( 6, 'TX34', GetDate() ), ( 6, 'TX35', GetDate() ),
( 6, 'TX36', GetDate() ), ( 6, 'TX37', GetDate() ),
( 7, 'TX38', GetDate() ), ( 7, 'TX39', GetDate() ), ( 7, 'TX35', GetDate() ),
( 7, 'TX36', GetDate() ), ( 7, 'TX37', GetDate() )
select * from (
select L.OrderId,
Max( case when L.Code = 'TX33' and R.Code = 'TX34' then 1 else 0 end ) as Mandatory,
Count( L.OrderId ) as Matches
from @Orders as L left outer join
@Orders as R on R.OrderId = L.OrderId and (
( L.Code = 'TX33' and R.Code = 'TX34' ) or
( L.Code = 'TX35' and R.Code = 'TX36' ) or
( L.Code = 'TX38' and R.Code = 'TX39' ) )
where L.PurchaseDate is not NULL and ( L.Code = 'TX37' or R.Code is not NULL )
group by L.OrderId ) as Arnold
where Mandatory = 1 and Matches > 1