计算 postgresql 位掩码中的相同位置位

Counting the same positional bits in postgresql bitmasks

我正在尝试计算 postgresql 中多个位掩码的每个相同位置位,这是一个问题示例:

假设我有三个位掩码(二进制),例如:

011011011100110
100011010100101
110110101010101

现在我要做的是获取每个单独列中的总位数,将上述掩码视为三行多列。

e.g 第一列有 count 2,第二列有 count 2,第三个有 个 1 等等...

实际上我在数据库中的每个位掩码中总共有 30 位。我想在 PostgreSQL 中进行。如果需要,我愿意进一步解释问题。

您可以使用 get_bit 函数和几个连接来完成:

SELECT sum(bit) FILTER (WHERE i = 0)  AS count_0,
       sum(bit) FILTER (WHERE i = 1)  AS count_1,
       ...
       sum(bit) FILTER (WHERE i = 29) AS count_29
FROM bits
   CROSS JOIN generate_series(0, 29) AS i
   CROSS JOIN LATERAL get_bit(b, i) AS bit;

在我的示例中,带有位串的列是 b

只要您的位串包含 63 位或更少,您就可以使用按位和 & 运算符和 bigint 算法:

# create table bmasks (mask bit(15));
CREATE TABLE

# insert into bmasks values ('011011011100110'), ('100011010100101'), ('110110101010101');
INSERT 0 3

# with masks as (
  select (2 ^ x)::bigint::bit(15) as mask, x as posn
    from generate_series(0, 14) as gs(x)
)
select m.posn, m.mask, sum((b.mask & m.mask > 0::bit(15))::int) as set_bits
  from masks m
       cross join bmasks b
 group by m.posn, m.mask;

┌──────┬─────────────────┬──────────┐
│ posn │      mask       │ set_bits │
├──────┼─────────────────┼──────────┤
│    0 │ 000000000000001 │        2 │
│    1 │ 000000000000010 │        1 │
│    2 │ 000000000000100 │        3 │
│    3 │ 000000000001000 │        0 │
│    4 │ 000000000010000 │        1 │
│    5 │ 000000000100000 │        2 │
│    6 │ 000000001000000 │        2 │
│    7 │ 000000010000000 │        2 │
│    8 │ 000000100000000 │        1 │
│    9 │ 000001000000000 │        2 │
│   10 │ 000010000000000 │        3 │
│   11 │ 000100000000000 │        1 │
│   12 │ 001000000000000 │        1 │
│   13 │ 010000000000000 │        2 │
│   14 │ 100000000000000 │        2 │
└──────┴─────────────────┴──────────┘
(15 rows)