如何在我的 T-SQL 查询中编写此 WHERE 过滤器以满足 2 个条件?

How to write this WHERE filter in my T-SQL Query that will cater for 2 conditions to be met?

我正在使用 SQL Server 2014,我有一个名为 ResStayDate 的 table,它按日期列出了 属性 的所有预订。这是 table:

的摘录
 ResaID    StayDate      PkgPlanCode      RateAmt
 61200     2015-01-11      COGB              0.00
 61200     2015-01-11      G1A810          152.00
 61200     2015-01-11      G1A810          152.00
 61200     2015-01-11      G1A810          152.00
 63500     2015-02-04      R2AI            125.00
 63500     2015-02-05      R2AI            125.00
 73850     2015-05-10      COGB              0.00
 73850     2015-05-10      G2450           169.00
 68901     2015-05-15      COFR              0.00
 68901     2015-05-15      COFR              0.00

我想要一个查询来输出所有 ResaID(加上 table 的剩余列),其中至少包含一个具有 PkgPlanCode "CO..." 及其对应的 RateAmt = 0 的 StayDate。如果特定 ResaID 的所有 StayDates 都有以 "CO..." 开头的 PkgPlanCodes 和它们对应的 RateAmt = 0,那么这些 ResaIDs 应该被排除在输出中。

换句话说,我的输出应该是这样的:

ResaID    StayDate      PkgPlanCode      RateAmt
 61200     2015-01-11      COGB              0.00
 61200     2015-01-11      G1A810          152.00
 61200     2015-01-11      G1A810          152.00
 61200     2015-01-11      G1A810          152.00
 73850     2015-05-10      COGB              0.00
 73850     2015-05-10      G2450           169.00

查询应排除 ResaID 63500(因为它不包含任何以 "CO..." 开头且 RateAmt = 0 的 PkgPlanCode)并且还排除 ResaID 68901(因为后者的所有 StayDate 都以 PkgPlanCode 开头"CO..." 和 RateAmt = 0)

我现在的查询如下(因为我不知道如何处理查询中的条件):

SELECT *

FROM ResStayDate

WHERE.......

使其成为复合WHERE条件,如

WHERE PkgPlanCode LIKE 'CO%'
AND RateAmt = 0.00

我们可以使用几个 CTEs to assess the conditions required and then use windowed aggregates 来确定条件是否 有时 ResaID 值中为真:

declare @t table (ResaID int,StayDate date,PkgPlanCode varchar(17),RateAmt decimal(13,2))
insert into @t(ResaID,StayDate,PkgPlanCode,RateAmt) values
 (61200,'20150111','COGB'  ,  0.00),
 (61200,'20150111','G1A810',152.00),
 (61200,'20150111','G1A810',152.00),
 (61200,'20150111','G1A810',152.00),
 (63500,'20150204','R2AI'  ,125.00),
 (63500,'20150205','R2AI'  ,125.00),
 (73850,'20150510','COGB'  ,  0.00),
 (73850,'20150510','G2450' ,169.00),
 (68901,'20150515','COFR'  ,  0.00),
 (68901,'20150515','COFR'  ,  0.00)

 ;With Assessment as (
    select ResaID,StayDate,PkgPlanCode,RateAmt,
         CASE WHEN PkgPlanCode like 'CO%' and RateAmt=0.0 THEN 1 ELSE 0 END as Cond
    from @t
), Groups as (
    select *,
        MIN(Cond) OVER (PARTITION BY ResaID) as MinCond,
        MAX(Cond) OVER (PARTITION BY ResaID) as MaxCond
    from
        Assessment
)
select * from Groups where MinCond < MaxCond

结果:

ResaID      StayDate   PkgPlanCode       RateAmt    Cond        MinCond     MaxCond
----------- ---------- ----------------- ---------- ----------- ----------- -----------
61200       2015-01-11 COGB              0.00       1           0           1
61200       2015-01-11 G1A810            152.00     0           0           1
61200       2015-01-11 G1A810            152.00     0           0           1
61200       2015-01-11 G1A810            152.00     0           0           1
73850       2015-05-10 COGB              0.00       1           0           1
73850       2015-05-10 G2450             169.00     0           0           1
WITH COPkgs As 
(   -- IDs for reservations with a CO* Package and 0 rate
    SELECT DISTINCT ResaID FROM ResStayDate Where PkgPlanCode LIKE 'CO%' AND RateAmt = 0
),
NonCOPkgs As
(   -- IDs for reservartions with a non-CO package
    SELECT DISTINCT ResaID FROM ResStayDate Where PkgPlanCode NOT LIKE 'CO%'
)
-- Reservation records that match IDs from BOTH previous sets
SELECT r.*
FROM ResStayDate r
INNER JOIN COPkgs c ON c.ResaID = r.ResaID 
INNER JOIN NonCOPkgs n on n.ResaID = r.ResaID