深入理解bit_or和bit_and,bit_count

bit_or:二进制数按位或,bit_and:二进制数按位与,bit_count:统计二进制数1个个数

下面以一个例子来说明用法: 示例要实现的功能就是计算每月有几天有访问,先把示例摘录在这里。

1 2 3 4 5 6 7 -- 创建表 CREATE TABLE t1 ( year YEAR (4), month INT (2) UNSIGNED ZEROFILL,               day INT (2) UNSIGNED ZEROFILL);   -- 插入测试数据 INSERT INTO t1 VALUES (2000,1,1),(2000,1,20),(2000,1,30),(2000,2,2),              (2000,2,23),(2000,2,23);

测试数据截图如下:

mysql> select*from t1;
+------+-------+------+
| year | month | day  |
+------+-------+------+
| 2000 |    01 |   01 |
| 2000 |    01 |   20 |
| 2000 |    01 |   30 |
| 2000 |    02 |   02 |
| 2000 |    02 |   23 |
| 2000 |    02 |   23 |
+------+-------+------+
6 rows in set (0.01 sec)

从上面的数据可以看出,1月份有3天有访问,2月份有2天访问。如果用group by来计算,需要使用两次,笔者自己写了个sql语句:

1 2 3 select year , month , count (0)      from ( select year , month , day , count (0) from t1 group by year , month , day ) as tmp      group by year , month ;

就是先按照year,month,day分组计算一次,将结果当成临时表再按照year,month分组计算一次。

官方手册上使用的这样的语句:

1 2 SELECT year , month ,BIT_COUNT(BIT_OR(1<< day )) AS days FROM t1         GROUP BY year , month ;

bit_count函数的含义

用来计算二进制数中包含1的个数。

1 select BIT_COUNT(10);

因为10转成二进制是1010,所以该结果就是2。

bit_or函数的含义

就是对两个二进制数进行或运算。如:

    1100
或  0101
--------------
    1101

上面例子中当计算2月份的访问天数时,

(1<< 02) | (1 << 23) | (1<<23) = 100 | 1000...(23个0)| 1000...(23个0) = 1000...100

再用bit_count一算就是2了,非常巧妙。

此处针对1<<day进行解释:这里的计数采取的是位图法,每天有访问就用1表示,02天表示100,23表示1000..(23个0)。
最后经过bit_or按位或后变成10000..(20个0)100,然后用bit_count统计2进制1的个数为2,非常巧妙

结果:

mysql> select year,month,bit_count(bit_or(1<<day)) as days from t1 group by year,month;
+------+-------+------+
| year | month | days |
+------+-------+------+
| 2000 |    01 |    3 |
| 2000 |    02 |    2 |
+------+-------+------+
2 rows in set (0.00 sec)

此外,还可以对day使用distinct来去重,得出每月有访问的天数:

mysql>  select year,month,count(distinct day) from t1 group by year,month;
+------+-------+---------------------+
| year | month | count(distinct day) |
+------+-------+---------------------+
| 2000 |    01 |                   3 |
| 2000 |    02 |                   2 |
+------+-------+---------------------+
2 rows in set (0.01 sec)

    原文作者:mysql
    原文地址: https://blog.csdn.net/koli6678/article/details/79841153
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞