2013-01-07 18 views
2

我在這裏找到了一個很好的資源( Comparing two bitmasks in SQL to see if any of the bits match ),用於在SQL數據庫中執行搜索,在這裏您使用位掩碼存儲具有多個屬性的數據。在這個例子中,所有的數據都是以int形式存儲的,where子句似乎只能用ints。在SQL中使用位串(而不是整數)匹配位掩碼

有沒有簡單的方法來轉換一個非常相似的測試用例來使用完整的位串呢?因此,而不是像一個例子:

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 

我可以來回轉換,但它更容易與實際位串形象化。對於我的簡單轉換(上面),我得到一個錯誤,即運算符不能用於位串。有沒有另外一種方法來設置這個工作?

+1

'SQL'是結構化查詢語言的總稱。你使用的是什麼DBMS?字符串和位運算符因DBMS而異。 –

+0

我正在使用Postgres – ten

回答

6

的一種方法是對錶達的右側只使用一個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'; 

或者你可以施放integer 0bit(3)

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

您可能感興趣的這個相關的答案演示了在boolean,bit stringinteger之間轉換的多種方法:
Can I convert a bunch of boolean columns to a single bitmap in PostgreSQL?

請注意,將數據存儲爲integer可以節省一些空間。 integer需要4字節用於信息的最多32個位,而 - 我引用manual at said location

的比特序列值,需要爲每個組8位,加5或 8字節的1字節取決於字符串的長度開銷 [...]

+0

太棒了,我知道我錯過了一些小事。感謝您的建議,儘管在這種情況下空間不是問題,因此增加可讀性可能更重要。 – ten