sql - 在 SQL 中使用位串(而不是整数)匹配位掩码

标签 sql postgresql match bitmask bitstring

我在这里找到了很棒的资源( Comparing two bitmasks in SQL to see if any of the bits match ) 用于在 SQL 数据库中进行搜索,您在其中使用位掩码存储具有多个属性的数据。不过,在示例中,所有数据都存储为整数,而 where 子句似乎只适用于整数。

有没有一种简单的方法可以将非常相似的测试用例转换为使用完整的位串?因此,而不是像这样的例子:

with test (id, username, roles)
AS
(
    SELECT 1,'Dave',1
    UNION SELECT 2,'Charlie',3
    UNION SELECT 3,'Susan',5
    UNION SELECT 4,'Nick',2
)
select * from test where (roles & 7) != 0 

取而代之的是:

with test (id, username, roles)
AS
(
    SELECT 1,'Dave',B'001'
    UNION SELECT 2,'Charlie',B'011'
    UNION SELECT 3,'Susan',B'101'
    UNION SELECT 4,'Nick',B'110'
)
select * from test where (roles & B'001') != 0 

我可以来回转换,但使用实际的位串更容易可视化。对于我的简单转换(上图),我得到一个错误,即运算符不适用于位串。是否有另一种可行的设置方法?

最佳答案

一种方法是只使用 bit string也在表达式的右侧:

WITH test (id, username, roles) AS (
   VALUES
     (1,'Dave',B'001')
    ,(2,'Charlie',B'011')
    ,(3,'Susan',B'101')
    ,(4,'Nick',B'110')
   )
SELECT *, (roles & B'001') AS intersection
FROM   test
WHERE  (roles & B'001') <> B'000';

或者您可以将整数 0 转换为 bit(3)

...
WHERE  (roles & B'001') <> 0::bit(3);

您可能对这个相关答案感兴趣,该答案演示了在booleanbit stringinteger 之间进行转换的多种方法:
Can I convert a bunch of boolean columns to a single bitmap in PostgreSQL?

请注意,将数据存储为 integer 可以节省一些空间。 integer 需要 4 个字节 来获取多达 32 位的信息,同时 - 我引用 manual at said location :

A bit string value requires 1 byte for each group of 8 bits, plus 5 or 8 bytes overhead depending on the length of the string [...]

关于sql - 在 SQL 中使用位串(而不是整数)匹配位掩码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14200486/

相关文章:

mysql - 选择比符合条件的行晚的所有行

sql - Spark DataFrame中IFNULL和IFF的等效SQL函数

sql - 将 PostgreSQL 函数包装在另一个函数中以有条件地组合结果

regex - Force -Match 运算符使表达式失败

r - 如何跨多个列匹配一列并在新列中返回匹配的 col_name

c# - 从 Web 服务器访问 SQL 数据库的合适方法

postgresql - 如何在触发器函数中选择多个变量?

sql - 来自不同表的条件连接

删除在 R 中开始和结束处包含句点的行

sql - 如何在不删除子表的情况下删除 PostgreSQL 中的表