为啥 MySQL BIT_OR() 返回的值与 PHP 位运算不同

Posted

技术标签:

【中文标题】为啥 MySQL BIT_OR() 返回的值与 PHP 位运算不同【英文标题】:Why MySQL BIT_OR() is returning different value than PHP bitwise operation为什么 MySQL BIT_OR() 返回的值与 PHP 位运算不同 【发布时间】:2015-01-31 10:43:51 【问题描述】:

我在 mysql 表中有以下数据

“数据转储” 2 电话呼叫 001 2 电话呼叫 010 2 电话呼叫 100 2 个电话呼叫 1000 2 phone_calls 10000 2 phone_calls 100000

如果我运行 php 代码来执行按位或这样的操作

echo bindec('001') | bindec('010') | bindec('100') | bindec('1000') | bindec('10000') | bindec('100000');

我得到 63 的输出“这是预期的”

如果我手动执行或操作

000001
000010
000100
001000
010000
100000
======
111111

the result = 111111 which is `32 + 16 + 8 + 4 + 2 + 1 = 63`

当我在 MySQL 中运行以下查询时

SELECT user_id, section_name, BIT_OR(permission_type) AS final
FROM permissions
WHERE section_name ='phone_calls' and user_id = 2
GROUP BY user_id, section_name

基本上是在上面列出的“数据转储”上运行BIT_OR(),输出是

 2  phone_calls 108543

为什么 MySQL 给我 108543 而 PHP 给我 63?如何让 MySQL 给我 63?

【问题讨论】:

【参考方案1】:

108543 是当您将or十进制1, 10, 100, 1000, 10000, 100000 组合在一起时得到的。

换句话说,它们没有被视为二进制值。

您需要为二进制等价物 1, 2, 4, 8, 16, 32 存储正确的十进制值,或者找到一种方法将仅包含01 数字的十进制变体转换为适当的值。

如果您想保留包含位模式的字符串,可以将它们转换为十进制,如下所示:

conv(colname,2,10)

这是一个base conversion:

mysql> select conv('10',2,10);
    -> '2'
mysql> select conv('1000',2,10);
    -> '8'

【讨论】:

我知道了:)我会给你正确的答案。但我为下面的下一个人留下了答案:) 非常感谢。我应该如何将列类型转换为***的转换? @Mike,您可以保持原样,因为该解决方案有效。我自己可能会存储一个整数类型而不是一个字符串,因为操作往往会更快,至少在常规数据库中是这样。 MySQL是否是这种情况,我不知道。如果它,正如我似乎记得的那样,以任何方式将所有内容存储为字符串,那么差异可能不会太大。无论如何,优化的第一条诫命是“衡量,不要猜测”,第二条是“检查你的权威,不要仅仅因为它们听起来知识渊博而相信互联网的一些随机机构”:-)【参考方案2】:

我明白了:)

SELECT user_id, section_name, BIT_OR(CONV(permission_type, 2, 10)) AS final
FROM data_import.permissions
WHERE section_name ='phone_calls' and user_id = 2
GROUP BY user_id, section_name

【讨论】:

以上是关于为啥 MySQL BIT_OR() 返回的值与 PHP 位运算不同的主要内容,如果未能解决你的问题,请参考以下文章

为啥 cv2.NORM_HAMMING 给出的值与实际汉明距离不同?

mysql中bit_count和bit_or使用

为啥 Oracle ADD_MONTHS() 返回的 sysdate 值与我硬编码今天的日期不同?

将逗号分隔的值与 MySQL 中的单列值匹配 [重复]

MYSQL - 如何在一个条件的值与另一个条件的值匹配的情况下运行查询?

MySQL:创建具有自动增量的表并将生成的值与同一表的不同列的值连接起来