为啥 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
存储正确的十进制值,或者找到一种方法将仅包含0
和1
数字的十进制变体转换为适当的值。
如果您想保留包含位模式的字符串,可以将它们转换为十进制,如下所示:
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 给出的值与实际汉明距离不同?
为啥 Oracle ADD_MONTHS() 返回的 sysdate 值与我硬编码今天的日期不同?