Access查询编写:统计A列0起105止的时间块数及块内B列100的块数
Access实现块统计的纯查询方案
实现思路
无需编写VBA脚本,通过多层嵌套Access查询即可完成全逻辑实现,兼容所有Access版本,核心逻辑分为四步,完全匹配给定的块划分规则:
- 为已按日期、时间升序排列的数据集生成连续行号
- 识别每个时间块的起始位置(A=0且上一行A值不为0)
- 为所有行分配所属的块编号
- 按块分组统计需求数值
以下实现假设你的原始表名为tbl_原始数据,包含字段Date、Time、A、B,排序逻辑和示例一致。
第一步:生成排序后的连续行号
通过域函数DCount统计当前行之前的记录数,生成唯一行号,保证排序逻辑和需求匹配:
SELECT Date, Time, A, B, DCount("*", "tbl_原始数据", "Date < #" & [Date] & "# OR (Date = #" & [Date] & "# AND Time < #" & [Time] & "#)" ) + 1 AS 行号 FROM tbl_原始数据 ORDER BY Date, Time;
将此查询保存为qry_行号生成。
第二步:标记每个块的起始行
通过自连接获取当前行的上一行A值,判断是否为块的起始行:
SELECT 当前.*, 上一行.A AS 上一行A, IIF( [A] = 0 AND (IsNull([上一行A]) OR [上一行A] <> 0), 1, 0 ) AS 是否块起始 FROM qry_行号生成 AS 当前 LEFT JOIN qry_行号生成 AS 上一行 ON 当前.行号 = 上一行.行号 + 1;
将此查询保存为qry_块起始标记。逻辑说明:只有连续A=0序列的第一行、或是整个数据集的首行(上行为空)才会被标记为块起始,后续连续的0值、105值行都不会触发块标记。
第三步:为所有行分配块编号
通过累计求和的方式,从第一行到当前行累加所有的块起始标记,得到当前行所属的块号:
SELECT *, DSum("是否块起始", "qry_块起始标记", "行号 <= " & [行号]) AS 块号 FROM qry_块起始标记;
将此查询保存为qry_块号分配。以示例数据验证:前5行(3个连续0值、2个连续105值)会被分配为块号1,后续7行(4个连续0值、3个连续105值)会被分配为块号2,和需求的块划分完全一致。
第四步:聚合统计最终结果
按块号分组,统计总块数(即A列要求的计数)、以及块内包含B=100值的块数(即B列要求的计数):
SELECT Count(块号) AS A列对应计数, Sum(块内含B100标记) AS B列对应计数 FROM ( SELECT 块号, Max(IIF([B] = 100, 1, 0)) AS 块内含B100标记 FROM qry_块号分配 GROUP BY 块号 );
验证说明
用给定的示例数据运行上述逻辑,输出结果完全匹配预期:A列计数=2、B列计数=1。逻辑天然兼容“下一个块开始前存在多个连续105值”的场景,所有连续105值都会被归到前序的块中,不会被单独识别为新块。
内容的提问来源于stack exchange,提问作者Shaves
相关产品推荐
相关产品推荐

