当前位置: 首页
数据库
如何在SQL中使用BIT_COUNT函数统计二进制位数量教程

如何在SQL中使用BIT_COUNT函数统计二进制位数量教程

热心网友 时间:2026-07-13
转载

BIT_COUNT函数统计无符号整数二进制中1的个数,输入必须为非负整数,字符串或负数会导致错误。使用前应确保字段为UNSIGNED类型或通过CAST转换。该函数不走索引,频繁查询建议缓存结果。MySQL特有,其他数据库需另写逻辑。对NULL返回NULL,需用IFNULL处理。

先说结论:BIT_COUNT 这个函数,在 MySQL 里用好了是神器,用错了就是坑。核心就是,它统计的是整数在无符号二进制形式下,“1”这个位出现的次数。不是字符串,不是十六进制文本,也不是拿个负数去跑补码位模式。

比如 BIT_COUNT(5) 返回 2,因为 5 的二进制是 101,看得出两个 1;BIT_COUNT(0) 自然是 0;但 BIT_COUNT(-1) 呢?MySQL 会先把它转成一个巨大的无符号数(64 位下是 18446744073709551615),然后数出来 64 个 1。嗯,这往往不是你要的结果。

如何使用SQL的BIT_COUNT函数统计二进制位?

函数到底在“数”什么?

所以,用之前得先确认一件事:你的字段,确实存的都是非负整数吗?最好是 TINYINT UNSIGNEDINT UNSIGNED 这种。否则结果不可靠,这是最容易出问题的地方。

几个常见的“我以为能行”的误操作

很多人以为 BIT_COUNT 可以直接扔进去一个字符串或者十六进制值,实际上一跑就发现不对劲:

  • BIT_COUNT('1010') 直接报错:Operand should be a number,字符串不是数字。
  • BIT_COUNT(UNHEX('A')) 返回 2——因为 UNHEX('A') 先转成字节 0x0A,也就是十进制 10,10 的二进制是 1010,有两个 1。但你要是想统计的是字母 "A" 这个字符的 ASCII 二进制里有多少个 1,那就完全跑偏了。
  • 有些表里权限字段是 TINYINT(有符号),还存了个负数。这时 BIT_COUNT 的结果会突然跳变,调试起来会非常头大。

正确的做法是什么样的?

  • 确保输入是无符号整数:建表时直接定义为 INT UNSIGNED,或者查询时用 CAST(col AS UNSIGNED) 强制转一下。
  • 如果原始数据是十六进制字符串,比如 'FF',那就先用 CONV('FF', 16, 10) 转成数字,再传给 BIT_COUNT
  • 字段语义必须是位图:也就是说,存的值本身就是拿来做位运算的,而且只写入非负值,否则就别折腾了。

真实查询和性能注意事项

假设有一张用户权限表,perms 列是 INT UNSIGNED,每个 bit 代表一个功能开关。想找出开启了超过 3 个功能的用户,很自然就会写:

SELECT user_id, perms, BIT_COUNT(perms) AS active_bits
FROM users
WHERE BIT_COUNT(perms) > 3;

这个查询能跑,但有几个地方需要特别留个心眼:

  • BIT_COUNT 是计算型函数,不走索引。所以 WHERE BIT_COUNT(perms) > 3 必然是全表扫描。
  • 如果业务经常按“开启的位数范围”来筛选,建议直接加一列 bit_count_cache TINYINT UNSIGNED,用触发器或者应用层维护这个值。
  • MySQL 8.0+ 支持函数索引,但你得用生成列的方式来建,比如虚拟列 + 索引,不是所有情况下都通用。

跨数据库的“陷阱”

这一点尤其需要警惕:BIT_COUNTMySQL 特有的函数。PostgreSQL、SQL Server、SQLite 都不支持同名函数。如果你在做的项目未来可能会从 MySQL 迁移到其他数据库,或者要同时兼容多个数据库,那就别指望 BIT_COUNT 能通用。

  • PostgreSQL:没有内置的 BIT_COUNT,得靠 LENGTH(REPLACE(TRANSLATE(x::text, '0', ''), '1', '')) 这类非常绕的写法,或者自定义函数。
  • SQL Server:通常要手动拆位,比如 (x & 1) + ((x >> 1) & 1) + ...,写起来很啰嗦。
  • SQLite:更没有,只能应用层处理或用扩展。

这意味着,位统计的逻辑最好下沉到应用层去处理,或者用可移植的表达式替代——虽然写起来更麻烦,但至少不会数据库一换就跑不起来了。

最后,还有一个容易让人踩坑的细节:BIT_COUNT 对 NULL 返回的是 NULL,不是 0。如果字段允许为空,别忘了加 IFNULL(BIT_COUNT(col), 0) 显式处理,否则筛选条件可能悄无声息地忽略掉一批数据。

来源:https://www.php.cn/faq/2778969.html

游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。

同类文章
更多
Redis 6.0 ACL权限控制:最小化命令授权提升安全性

Redis 6.0 ACL权限控制:最小化命令授权提升安全性

Redis6 0及以上版本启用ACL时,需确认版本并修改default用户默认全开权限。按业务边界创建用户,严格绑定keypattern(如~order:*),避免漏写通配符。命令权限按输入顺序生效,推荐细粒度列举而非类别。客户端连接必须显式传递用户名,否则回退至default用户导致权限失效。

时间:2026-07-13 07:07
导出数据库时包含创建数据库语句的选项设置

导出数据库时包含创建数据库语句的选项设置

使用mysqldump导出时,默认不包含建库语句,需添加--databases参数才能生成CREATEDATABASE和USE语句。同时,导出账号必须拥有SHOWDATABASES权限,否则会报错。注意--no-create-db参数会覆盖建库语句,导致不生成建库指令,导入前需检查目标库是否存在,并确保字符集兼容。

时间:2026-07-13 07:07
SQL嵌套查询使用Union与Intersect集合运算符过滤

SQL嵌套查询使用Union与Intersect集合运算符过滤

嵌套查询中不可直接在WHERE或IN中使用UNION或INTERSECT。正确做法是将集合运算符包裹在括号内作为派生表置于FROM子句中,并显式赋予别名。对于不支持INTERSECT的数据库,可用EXISTS嵌套替代。需注意列类型对齐、别名不可省略等细节。

时间:2026-07-13 07:07
如何在SQL中使用BIT_COUNT函数统计二进制位数量教程

如何在SQL中使用BIT_COUNT函数统计二进制位数量教程

BIT_COUNT函数统计无符号整数二进制中1的个数,输入必须为非负整数,字符串或负数会导致错误。使用前应确保字段为UNSIGNED类型或通过CAST转换。该函数不走索引,频繁查询建议缓存结果。MySQL特有,其他数据库需另写逻辑。对NULL返回NULL,需用IFNULL处理。

时间:2026-07-13 07:07
SQL中利用JOIN查找A表不存在B表的数据

SQL中利用JOIN查找A表不存在B表的数据

在SQL中查找A表存在而B表不存在的记录,最可靠的写法是使用LEFTJOIN并结合WHEREB idISNULL。需注意ON只用于连接逻辑,过滤条件应放在WHERE子句中;B表关联字段需要建立索引,并且要避免NULL值的陷阱。不建议使用NOTIN或EXCEPT,因为它们容易出错且性能较差。

时间:2026-07-13 07:06
热门专题
更多
刀塔传奇破解版无限钻石下载大全 刀塔传奇破解版无限钻石下载大全
洛克王国正式正版手游下载安装大全 洛克王国正式正版手游下载安装大全
思美人手游下载专区 思美人手游下载专区
好玩的阿拉德之怒游戏下载合集 好玩的阿拉德之怒游戏下载合集
不思议迷宫手游下载合集 不思议迷宫手游下载合集
百宝袋汉化组游戏最新合集 百宝袋汉化组游戏最新合集
jsk游戏合集30款游戏大全 jsk游戏合集30款游戏大全
宾果消消消原版下载大全 宾果消消消原版下载大全
  • 热门数据榜