You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过单SQL查询统计64位状态字段中各任务的完成用户数?

优雅解决64位状态位的单查询统计方案

嘿,我完全懂你这种要查64次的痛苦!其实不用逐个任务去查,我们可以借助数字序列生成+字符串/位运算的方式,用一次查询搞定所有任务的完成数统计。下面分两种常见的存储场景给你具体方案:

场景1:status是字符串类型(比如CHAR(64))

如果你的status是按十进制字符串存储的(比如示例里的1100、1001这种),我们可以先生成1到64的任务编号序列,然后批量提取每个任务对应的位并求和:

MySQL示例代码

WITH RECURSIVE task_ids AS (
    SELECT 1 AS task_id
    UNION ALL
    SELECT task_id + 1 FROM task_ids WHERE task_id < 64
)
SELECT
    ti.task_id,
    SUM(CAST(SUBSTRING(your_table.status, ti.task_id, 1) AS UNSIGNED)) AS completed_user_count
FROM task_ids ti
CROSS JOIN your_table
GROUP BY ti.task_id
ORDER BY ti.task_id;

小提示:

  • 如果你的任务编号是从右往左对应字符串的位(比如字符串最后一位是任务1),把SUBSTRING的位置参数改成LENGTH(your_table.status) - ti.task_id + 1就行。
  • 要是你的数据库不支持递归CTE(比如MySQL 5.x),提前建个包含1到64的数字表(比如叫numbers)替换掉CTE部分就行。

场景2:status是整数类型(用二进制位存状态)

如果status实际是用64位整数的二进制位来记录状态(比如十进制10对应二进制1010,代表任务2、4完成),那用位运算效率会更高:

MySQL示例代码

WITH RECURSIVE task_ids AS (
    SELECT 1 AS task_id
    UNION ALL
    SELECT task_id + 1 FROM task_ids WHERE task_id < 64
)
SELECT
    ti.task_id,
    SUM( (your_table.status >> (ti.task_id - 1)) & 1 ) AS completed_user_count
FROM task_ids ti
CROSS JOIN your_table
GROUP BY ti.task_id
ORDER BY ti.task_id;

原理说明:

  • >> (ti.task_id - 1):把目标任务对应的二进制位右移到最低位(比如任务1对应第0位,所以移0位;任务2对应第1位,移1位)。
  • & 1:提取最低位的数值(0或1),然后用SUM直接统计完成的用户数。

额外优化建议

如果你的数据量特别大,CROSS JOIN可能会生成较多临时数据,不过64次的笛卡尔积其实还好,百万级数据也能轻松处理。要是担心性能,也可以把数字序列表做成物理表,提前插入1到64的记录,查询时直接关联就行。


内容的提问来源于stack exchange,提问作者user2894829

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 16:37:37