如何在MSSQL 2016中筛选当日从未被处理的Zuora对象
需求:筛选当日从未被处理过的Zuora Object名称
要求返回**当日所有运行记录均未处理(processed≠1)**的Zuora Object名称;若某Object当日存在至少一条已处理(processed=1)的记录,无论其他记录状态如何,均需排除。
测试表结构
CREATE TABLE ZuoraSyncLog ( LogID INT IDENTITY(1,1) PRIMARY KEY, ZuoraObjectName VARCHAR(50) NOT NULL, Processed BIT NOT NULL, SyncDate DATETIME NOT NULL );
测试数据插入
-- Account对象:当日有1条已处理记录,2条未处理 INSERT INTO ZuoraSyncLog (ZuoraObjectName, Processed, SyncDate) VALUES ('Account', 0, CAST(GETDATE() AS DATE)), ('Account', 1, CAST(GETDATE() AS DATE)), ('Account', 0, CAST(GETDATE() AS DATE)); -- Subscription对象:当日所有记录均未处理 INSERT INTO ZuoraSyncLog (ZuoraObjectName, Processed, SyncDate) VALUES ('Subscription', 0, CAST(GETDATE() AS DATE)), ('Subscription', 0, CAST(GETDATE() AS DATE)); -- 非当日数据,不参与筛选 INSERT INTO ZuoraSyncLog (ZuoraObjectName, Processed, SyncDate) VALUES ('Account', 1, DATEADD(DAY, -1, CAST(GETDATE() AS DATE)));
原查询常见问题
若原查询仅通过WHERE Processed=0+GROUP BY筛选,会错误包含那些存在已处理记录的Object(比如示例中的Account),因为该Object仍有未处理记录满足WHERE条件,无法排除整体存在已处理记录的情况。
正确查询方法
方法1:GROUP BY + HAVING 聚合判断
利用聚合函数判断该Object当日是否存在已处理记录,仅保留无任何已处理记录的Object:
SELECT ZuoraObjectName FROM ZuoraSyncLog WHERE SyncDate = CAST(GETDATE() AS DATE) -- 限定当日数据 GROUP BY ZuoraObjectName HAVING MAX(CAST(Processed AS INT)) = 0; -- 所有记录的processed最大值为0,即无1的情况
方法2:NOT EXISTS 子查询
查询当日不存在processed=1记录的Object:
SELECT DISTINCT ZuoraObjectName FROM ZuoraSyncLog z1 WHERE SyncDate = CAST(GETDATE() AS DATE) AND NOT EXISTS ( SELECT 1 FROM ZuoraSyncLog z2 WHERE z2.ZuoraObjectName = z1.ZuoraObjectName AND z2.SyncDate = CAST(GETDATE() AS DATE) AND z2.Processed = 1 );
结果验证
上述两种查询均会返回:
ZuoraObjectName --------------- Subscription
Account因存在当日已处理记录,会被正确排除。
内容的提问来源于stack exchange,提问作者Vikas J
相关产品推荐
相关产品推荐

