如何遍历TADOQuery查询结果集并根据check_id的记录数执行特定代码块
针对你的需求,我提供几个实用的实现思路,都是基于Delphi中TADOQuery的操作逻辑,你可以根据自己的场景选择最适合的:
方案1:客户端先统计各check_id的总记录数
这种方式适合结果集规模不大的情况,先遍历一遍结果集统计每个check_id的记录数量,再根据统计值执行对应代码块:
var CheckIDCount: TDictionary<Integer, Integer>; Qry: TADOQuery; CheckID: Integer; begin CheckIDCount := TDictionary<Integer, Integer>.Create; try // 假设你的TADOQuery已经打开并加载了CTE结果 Qry.First; while not Qry.Eof do begin CheckID := Qry.FieldByName('check_id').AsInteger; if CheckIDCount.ContainsKey(CheckID) then CheckIDCount[CheckID] := CheckIDCount[CheckID] + 1 else CheckIDCount.Add(CheckID, 1); Qry.Next; end; // 处理check_id 50001的情况 if CheckIDCount.ContainsKey(50001) and (CheckIDCount[50001] = 1) then begin // 这里写check_id50001仅1条时要执行的代码 ShowMessage('check_id 50001只有1条记录'); end; // 处理check_id 50003的情况 if CheckIDCount.ContainsKey(50003) and (CheckIDCount[50003] = 1) then begin // 这里写check_id50003仅1条时要执行的代码 ShowMessage('check_id 50003只有1条记录'); end; // 处理check_id 50002的情况 if CheckIDCount.ContainsKey(50002) and (CheckIDCount[50002] >= 2) then begin // 这里写check_id50002有2条及以上时要执行的代码 ShowMessage('check_id 50002共有' + IntToStr(CheckIDCount[50002]) + '条记录'); end; finally CheckIDCount.Free; end; end;
方案2:在CTE中直接加入统计字段(更高效)
如果你的结果集比较大,建议直接在SQL层面完成统计,减少客户端的遍历开销。修改你的CTE查询,加入COUNT(*) OVER (PARTITION BY check_id)来获取每个check_id的总记录数:
WITH YourOriginalCTE AS ( -- 这里是你原来的CTE查询语句 ) SELECT row_num, buyer_id, amount, check_id, COUNT(*) OVER (PARTITION BY check_id) AS check_total_count FROM YourOriginalCTE
然后在客户端遍历的时候,直接读取这个统计字段判断即可,还可以用一个集合避免重复处理同一个check_id:
var ProcessedCheckIDs: TSet<Integer>; Qry: TADOQuery; CheckID, CheckTotal: Integer; begin ProcessedCheckIDs := TSet<Integer>.Create; try Qry.First; while not Qry.Eof do begin CheckID := Qry.FieldByName('check_id').AsInteger; CheckTotal := Qry.FieldByName('check_total_count').AsInteger; // 避免同一个check_id重复触发代码块 if not ProcessedCheckIDs.Contains(CheckID) then begin case CheckID of 50001, 50003: if CheckTotal = 1 then begin // 执行对应代码块 ShowMessage(Format('check_id %d 仅1条记录,执行对应逻辑', [CheckID])); ProcessedCheckIDs.Add(CheckID); end; 50002: if CheckTotal >= 2 then begin // 执行对应代码块 ShowMessage(Format('check_id %d 有%d条记录,执行对应逻辑', [CheckID, CheckTotal])); ProcessedCheckIDs.Add(CheckID); end; end; end; Qry.Next; end; finally ProcessedCheckIDs.Free; end; end;
方案3:按buyer_id分组处理(如果需求是针对每个买家的check_id记录数)
如果你的需求是每个buyer_id下的check_id记录数(比如每个买家的某个check_id是否满足数量条件),可以用嵌套字典来统计:
type TBuyerCheckCount = TDictionary<Integer, Integer>; // Key: check_id, Value: 记录数 var BuyerCheckCounts: TDictionary<Integer, TBuyerCheckCount>; Qry: TADOQuery; BuyerID, CheckID: Integer; BuyerCount: TBuyerCheckCount; begin BuyerCheckCounts := TDictionary<Integer, TBuyerCheckCount>.Create; try Qry.First; while not Qry.Eof do begin BuyerID := Qry.FieldByName('buyer_id').AsInteger; CheckID := Qry.FieldByName('check_id').AsInteger; // 获取当前买家的check_id统计字典,不存在则创建 if not BuyerCheckCounts.TryGetValue(BuyerID, BuyerCount) then begin BuyerCount := TBuyerCheckCount.Create; BuyerCheckCounts.Add(BuyerID, BuyerCount); end; // 更新当前check_id的记录数 if BuyerCount.ContainsKey(CheckID) then BuyerCount[CheckID] := BuyerCount[CheckID] + 1 else BuyerCount.Add(CheckID, 1); Qry.Next; end; // 遍历每个买家的统计结果 for BuyerID in BuyerCheckCounts.Keys do begin BuyerCount := BuyerCheckCounts[BuyerID]; Writeln(Format('处理买家%d的记录', [BuyerID])); if BuyerCount.ContainsKey(50001) and (BuyerCount[50001] = 1) then begin // 当前买家的check_id50001仅1条,执行代码 Writeln(Format('买家%d的check_id50001仅1条', [BuyerID])); end; if BuyerCount.ContainsKey(50003) and (BuyerCount[50003] = 1) then begin // 当前买家的check_id50003仅1条,执行代码 Writeln(Format('买家%d的check_id50003仅1条', [BuyerID])); end; if BuyerCount.ContainsKey(50002) and (BuyerCount[50002] >= 2) then begin // 当前买家的check_id50002有2条及以上,执行代码 Writeln(Format('买家%d的check_id50002有%d条', [BuyerID, BuyerCount[50002]])); end; end; finally // 释放嵌套的字典资源 for BuyerCount in BuyerCheckCounts.Values do BuyerCount.Free; BuyerCheckCounts.Free; end; end;
你可以根据自己的实际需求(是全局统计还是按买家分组)来选择对应的方案,代码里的示例逻辑可以替换成你实际要执行的业务代码。
内容的提问来源于stack exchange,提问作者Blacklight
相关产品推荐
相关产品推荐

