4

我在这里找到了一个很好的资源( 比较 SQL 中的两个位掩码以查看是否有任何位匹配 ),用于在 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 

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

4

1 回答 1

7

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

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';

或者你可以integer 0投到bit(3)

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

您可能对此相关答案感兴趣,该答案演示了在和之间boolean进行转换的多种方法:我可以在 PostgreSQL 中将一堆布尔列转换为单个位图吗?bit stringinteger

请注意,将数据存储为integer可以节省一些空间。最多 32 位信息integer需要4 个字节,而 - 我在所述位置引用手册

位串值每组 8 位需要1 个字节,加上 5 或 8 个字节的开销,具体取决于字符串的长度 [...]

于 2013-01-07T21:25:21.387 回答