postgresql - Postgres bitmask group by -
i have following flags declared:
0 - none 1 - read 2 - write 4 - view i want write query group on bitmask , count of each flag used.
person mask 0 b 3 c 7 d 6 the result should be:
flag count none 1 read 2 write 3 view 2 any tips appreciated.
for craig
select lea.mask trackerstatusmask, count(*) count live le inner join ( ... --some guff ) lea on le.xid = lea.xid le.xid = p_xid group lea.mask;
simplest - pivoted result
here's how i'd approach it:
-- (after fixing idiotic mistakes in first version) select count(nullif(mask <> 0, true)) "none", count(nullif(mask & 2,0)) "write", count(nullif(mask & 1,0)) "read", count(nullif(mask & 4,0)) "view" my_table; -- ... though @clodaldo's version of below considerably clearer, per comments. this doesn't group by such; instead scans table , collects data in single pass, producing column-oriented results.
if need in row form can pivot result, either using crosstab function tablefunc module or hand.
if must group by, explode bitmask
you cannot use group by in simple way, because expects rows fall 1 group. rows appear in multiple groups. if must use group by have generating "exploded" bitmask 1 input row gets copied produce multiple output rows. can done lateral function invocation in 9.3, or srf-in-select in 9.2, or doing join on values clause:
select case when mask_bit = 1 'read' when mask_bit = 2 'write' when mask_bit = 4 'view' when mask_bit null 'none' end "flag", count(person) "count" t left outer join ( values (4),(2),(1) ) mask_bits(mask_bit) on (mask & mask_bit = mask_bit) group mask_bit; i don't think you'll have luck making efficient single table scan, though.
Comments
Post a Comment