4

ビットマスクを使用して複数のプロパティを持つデータを格納している SQL データベースで検索を行うための優れたリソースをここで見つけました ( SQL で 2 つのビットマスクを比較して、ビットのいずれかが一致するかどうかを確認します)。ただし、この例では、すべてのデータが int として格納されており、where 句は int でのみ機能するようです。

非常によく似たテスト ケースを変換して、代わりに完全なビット文字列を使用する簡単な方法はありますか? したがって、次のような例の代わりに:

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

1 つの方法は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または、 toをキャストできますbit(3)

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

との間booleanで変換するいくつかの方法を示すこの関連する回答に興味があるかもしれません: PostgreSQL で boolean 列の束を単一のビットマップに変換できますか?bit stringinteger

データを as として保存するとinteger、スペースを節約できることに注意してください。最大32ビットの情報に4バイトintegerが必要ですが、-上記の場所にあるマニュアルを引用します:

ビット文字列値には、8 ビットのグループごとに1 バイトと、文字列の長さに応じて5 または 8 バイトのオーバーヘッドが必要です [...]

于 2013-01-07T21:25:21.387 に答える