在 SQL 中分解位掩码

Breaking a bitmask down in SQL

我正在使用一个使用位掩码的旧数据库设计。我有 table,其中包含电子邮件地址和基于另一个 table 的位掩码,并且我的任务是编写一个 SQL 查询,其中 "breaks down" 这些位掩码。通常,以不同的方式查看此数据,我们使用按位 & 来确定位掩码是否有效,但这次不是这样...

在我的数据的简化版本中,我有 2 个这样的字段。

|---------------------|------------------|
|      Email          |     bitMask      |
|---------------------|------------------|
|     test@test.com   |        3         |
|---------------------|------------------|
|    test2@test.com   |        9         |
|---------------------|------------------| 

我最终要寻找的输出会显示 "powers of 2" 或 "bits" 到达位掩码所需的内容,因此我可以在另一个 [=] 中交叉引用掩码值25=]。所以我的样本输出是这样的:

|---------------------|------------------|
|      Email          |     value        |
|---------------------|------------------|
|     test@test.com   |        2         |
|---------------------|------------------|
|     test@test.com   |        1         |
|---------------------|------------------|
|    test2@test.com   |        8         |
|---------------------|------------------| 
|    test2@test.com   |        1         |
|---------------------|------------------| 

这与我过去处理位掩码的方式相反。如果有人知道如何编写此查询,我们将不胜感激。

使用 &(按位与运算符),使用 0xFFFFFFFE 获得 2 部分的 次幂,使用 1 获得第一个二进制数字(01):

select [Email], [bitMask] & 0xFFFFFFFE [value]
from tablename  
union all
select [Email], [bitMask] & 1
from tablename  
order by [Email], [value] desc

参见demo
结果:

> Email          | value
> :------------- | ----:
> test@test.com  |     2
> test@test.com  |     1
> test2@test.com |     8
> test2@test.com |     1